map_visualizer.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. $REQUIRE_LIB['shjs'] = "";
  3. $REQUIRE_LIB['dracula'] = "";
  4. $REQUIRE_LIB['base64'] = "";
  5. $REQUIRE_LIB['raphael'] = "";
  6. echoUOJPageHeader("图可视化");
  7. ?>
  8. <div class="container">
  9. <div class="row">
  10. <div class="col-md-3">
  11. <div class="form-check">
  12. <input class="form-check-input" type="checkbox" id="directed" name="directed">
  13. <label class="form-check-label" for="directed">
  14. 是否有向
  15. </label>
  16. </div>
  17. <div class="form-group">
  18. <textarea class="form-control" id="edges" rows="3" placeholder="格式:
  19. 第一条边起点 第一条边终点 [第一条边权重]
  20. 第二条边起点 第二条边终点 [第二条边权重]
  21. 第三条边起点 第三条边终点 [第三条边权重]
  22. 如:
  23. 1 2
  24. 2 3
  25. 1 3 2
  26. "></textarea>
  27. </div>
  28. <?php if (UOJConfig::$data['tools']['map-copy-enabled']): ?>
  29. <button type="button" class="btn btn-secondary" id="copy">复制图片</button>
  30. <?php endif ?>
  31. </div>
  32. <div class="col-md-9" id="paper">
  33. </div>
  34. </div>
  35. </div>
  36. <script>
  37. (function () {
  38. <?php if (UOJConfig::$data['tools']['map-copy-enabled']): ?>
  39. $("#copy").click(function () {
  40. if(navigator.permissions) {
  41. navigator.permissions.query({name: "clipboard-write"}).then(result => {
  42. if (result.state === "granted" || result.state === "prompt") {
  43. let paper = $("#paper")
  44. // First, we create an canvas and a img which has the same size with the canvas.
  45. let canvas = document.createElement('canvas');
  46. let s_img = document.createElement('img');
  47. s_img.height = paper.height()
  48. s_img.width = paper.width()
  49. canvas.height = paper.height()
  50. canvas.width = paper.width()
  51. // After this image is loaded, we draw it on our canvas
  52. s_img.onload = function () {
  53. // On some browsers, the exported png have a black background.
  54. // So we will draw a white background first.
  55. ctx = canvas.getContext('2d');
  56. ctx.beginPath();
  57. ctx.rect(0, 0, paper.width(), paper.height());
  58. ctx.fillStyle = "white";
  59. ctx.fill();
  60. // We put our image created from the svg to the canvas
  61. canvas.getContext('2d').drawImage(s_img, 0, 0);
  62. // Then we export canvas as a png file, paste it to clipboard.
  63. canvas.toBlob(function (blob) {
  64. const item = new ClipboardItem({[blob.type]: blob});
  65. navigator.clipboard.write([item]).then(function () {
  66. alert("图片已经复制到剪切板中");
  67. }, function (err) {
  68. alert(err);
  69. });
  70. });
  71. }
  72. // Load our svg to this image.
  73. s_img.src = "data:image/svg+xml;base64," + Base64.encode(new XMLSerializer().serializeToString(document.querySelector("#paper > svg")));
  74. } else {
  75. alert("获取剪切板权限失败, 请打开网页设置并授予剪切板权限!")
  76. }
  77. });
  78. } else {
  79. alert("获取剪切板权限失败, 请使用最新Chrome浏览器, 打开网页设置并授予剪切板权限!")
  80. }
  81. })
  82. <?php endif ?>
  83. let repaint = function () {
  84. let paper = $("#paper");
  85. // Clear existing elements.
  86. paper.html("");
  87. let directed = $('#directed').is(":checked");
  88. let Graph = Dracula.Graph;
  89. let Renderer = Dracula.Renderer.Raphael;
  90. let Layout = Dracula.Layout.Spring;
  91. let graph = new Graph();
  92. let render = function(r, n) {
  93. let color = Raphael.getColor();
  94. return r.set()
  95. .push(
  96. r.ellipse(0, 0, 30, 20).attr({stroke: color, "stroke-width": 2, fill: color, "fill-opacity": 0})
  97. )
  98. .push(r.text(0, 0, n.id).attr({ opacity: 1, 'font-size': 20,}));
  99. }
  100. $("#edges").val().split("\n").forEach(function (edge) {
  101. if (edge.split(" ").length >= 2) {
  102. if (edge.split(" ")[0].length !== 0 && edge.split(" ")[1].length !== 0 ){
  103. graph.addNode(edge.split(" ")[0], {
  104. render: render
  105. });
  106. graph.addNode(edge.split(" ")[1], {
  107. render: render
  108. });
  109. graph.addEdge(edge.split(" ")[0], edge.split(" ")[1], {
  110. directed: directed,
  111. label:edge.split(" ")[2],
  112. 'label-style' : {
  113. 'font-size': 20,
  114. "fill-opacity":"1"
  115. }
  116. });
  117. }
  118. }
  119. })
  120. var layout = new Layout(graph)
  121. var renderer = new Renderer('#paper', graph, paper.width(), paper.height())
  122. renderer.draw()
  123. }
  124. $("#edges").on("input", repaint)
  125. $("#directed").on("input", repaint)
  126. })()
  127. </script>
  128. <?php
  129. echoUOJPageFooter();