• 前端用JavaScript实现桑基图(Sankey图)


    前端用JavaScript实现桑基图(Sankey图)

    桑基图(Sankey图),是流图的一种,常用来展示事物的数量、发展方向、数据量大小等,在可视化分析中经常使用。

    本文,演示如何在前端用JavaScript绘制桑基图。注:本例使用JShaman数据展示JS代码混淆加密流程。

    先看效果:

    因为已有成熟的库可用,比如,可以使用d3引擎,所以sankey的实现较为简单。

    众所周知,JShaman是国内知名的JS代码混淆加密平台,我们将用JShaman英文版的混淆返回内容做为数据源,绘制一张JS代码混淆加密流程桑基图。

    JShaman数据采集,直接复制即可:

    用d3实现桑基图绘制,核心代码如下,文末会提供完整代码。

    绘图成功:

    桑基图效果说明:从图中,可以看到JShaman对JS代码的混淆加密流程:初始的JS代码,先转为AST(抽象语法树),再进行String reverse、Dead Code Insertion、Eval Encryption等数十种混淆加密操作,生成了新的AST,最后再根据AST重新生成JS代码,这便是JS代码混淆加密的完整流程,由图可以让人一目了然的知晓全过程。

    最后,附上完整代码,如果您也需要绘制桑基图,可以参考此代码:

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
    7. <script src="./libs/d3/d3.min.js"></script>
    8. <script src="./libs/d3-sankey/d3-sankey.js"></script>
    9. <script src="./libs/d3-sankey-util.js"></script>
    10. </head>
    11. <body>
    12. <div id="obfuscate_sankey"></div>
    13. <script>
    14. obfuscate_result = {
    15. "status": [
    16. {
    17. "feature": "JavaScript 2 AST",
    18. "time": "2023/09/14 07:56:36",
    19. "status": 282
    20. },
    21. {
    22. "feature": "Encode JSON",
    23. "time": "2023/09/14 07:56:36",
    24. "status": 0
    25. },
    26. {
    27. "feature": "Encode Regexp",
    28. "time": "2023/09/14 07:56:36",
    29. "status": 0
    30. },
    31. {
    32. "feature": "String reverse",
    33. "time": "2023/09/14 07:56:36",
    34. "status": 2
    35. },
    36. {
    37. "feature": "Dead Code Insertion",
    38. "time": "2023/09/14 07:56:36",
    39. "status": 4
    40. },
    41. {
    42. "feature": "Rename Private Identifiers",
    43. "time": "2023/09/14 07:56:36",
    44. "status": 2
    45. },
    46. {
    47. "feature": "Rename Global Identifiers",
    48. "time": "2023/09/14 07:56:36",
    49. "status": 2
    50. },
    51. {
    52. "feature": "Rename Global Functions",
    53. "time": "2023/09/14 07:56:36",
    54. "status": 1
    55. },
    56. {
    57. "feature": "Rename Private Functions",
    58. "time": "2023/09/14 07:56:36",
    59. "status": 0
    60. },
    61. {
    62. "feature": "AST Executing",
    63. "time": "2023/09/14 07:56:36",
    64. "status": 9
    65. },
    66. {
    67. "feature": "Property Indirection",
    68. "time": "2023/09/14 07:56:36",
    69. "status": 34
    70. },
    71. {
    72. "feature": "Assignment To Function",
    73. "time": "2023/09/14 07:56:36",
    74. "status": 6
    75. },
    76. {
    77. "feature": "Numbers To Expressions",
    78. "time": "2023/09/14 07:56:36",
    79. "status": 9
    80. },
    81. {
    82. "feature": "VM Executing",
    83. "time": "2023/09/14 07:56:36",
    84. "status": 15
    85. },
    86. {
    87. "feature": "Expression To Function",
    88. "time": "2023/09/14 07:56:36",
    89. "status": 30
    90. },
    91. {
    92. "feature": "Boolean Encoding",
    93. "time": "2023/09/14 07:56:36",
    94. "status": 30
    95. },
    96. {
    97. "feature": "Eval Encryption",
    98. "time": "2023/09/14 07:56:36",
    99. "status": 27
    100. },
    101. {
    102. "feature": "Encode Strings",
    103. "time": "2023/09/14 07:56:36",
    104. "status": 33
    105. },
    106. {
    107. "feature": "Control Flow Flattening",
    108. "time": "2023/09/14 07:56:36",
    109. "status": 15
    110. },
    111. {
    112. "feature": "Control Flow Shrinking",
    113. "time": "2023/09/14 07:56:36",
    114. "status": 3
    115. },
    116. {
    117. "feature": "String Array",
    118. "time": "2023/09/14 07:56:36",
    119. "status": 41
    120. },
    121. {
    122. "feature": "String Array Encoding",
    123. "time": "2023/09/14 07:56:36",
    124. "status": 41
    125. },
    126. {
    127. "feature": "AST 2 JavaScript",
    128. "time": "2023/09/14 07:56:36",
    129. "status": 5086
    130. }
    131. ]
    132. }
    133. var label = [{"name":"JavaScript"},{"name":"AST"}];
    134. var source = [0];
    135. var target =[1];
    136. var value = [obfuscate_result.status[0].status];
    137. for(i=1; i<obfuscate_result.status.length-1; i++){
    138. label.push({"name":obfuscate_result.status[i].feature + " " + obfuscate_result.status[i].status} );
    139. source.push(1)
    140. target.push(i+1);
    141. if(obfuscate_result.status[i].status == 0){
    142. obfuscate_result.status[i].status =1;
    143. }
    144. value.push(obfuscate_result.status[i].status);
    145. source.push(i+1)
    146. target.push(obfuscate_result.status.length);
    147. value.push(obfuscate_result.status[i].status);
    148. }
    149. label.push({"name":"AST"});
    150. label.push({"name":"ObFuscated JavaScript"});
    151. source.push(label.length-2)
    152. target.push(label.length-1);
    153. value.push(obfuscate_result.status[obfuscate_result.status.length-1].status);
    154. var sankey_data= {}
    155. sankey_data.nodes = label;
    156. sankey_data.links = [];
    157. for(i=0;i<source.length;i++){
    158. sankey_data.links.push({"source":source[i],"target":target[i],"value":value[i]});
    159. }
    160. renderSankey({
    161. el: 'obfuscate_sankey',
    162. layoutStyle: {
    163. width: 1000,
    164. height: 680
    165. },
    166. data: sankey_data
    167. })
    168. </script>
    169. </body>
    170. </html>

  • 相关阅读:
    U-Mail信创邮件系统解决方案
    <Linux进程概念>——《Linux》
    【深度学习】分类问题探究(多标签分类转为多个二分类,等)
    SQL注入漏洞(绕过篇)
    ArcGIS导出Excel中文乱码及shp添加字段3个字被截断
    C++面向对象程序设计(第2版)第六章(多态性与虚函数)知识点总结
    基于openEuler虚拟机本地执行mugen测试脚本
    LintCode 124 Longest Consecutive Sequence (unordered_set的应用)
    (附源码)python主机硬件配置推荐系统 毕业设计 231155
    ubuntu18.04 禁用自带nouveau后重启无法进入系统
  • 原文地址:https://blog.csdn.net/w2sft/article/details/132962582