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

news2024/11/16 18:07:50

前端用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代码混淆加密的完整流程,由图可以让人一目了然的知晓全过程。

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="./libs/d3/d3.min.js"></script>
<script src="./libs/d3-sankey/d3-sankey.js"></script>
<script src="./libs/d3-sankey-util.js"></script>
</head>
<body>
<div id="obfuscate_sankey"></div>
<script>
obfuscate_result = {
"status": [
{
"feature": "JavaScript 2 AST",
"time": "2023/09/14 07:56:36",
"status": 282
},
{
"feature": "Encode JSON",
"time": "2023/09/14 07:56:36",
"status": 0
},
{
"feature": "Encode Regexp",
"time": "2023/09/14 07:56:36",
"status": 0
},
{
"feature": "String reverse",
"time": "2023/09/14 07:56:36",
"status": 2
},
{
"feature": "Dead Code Insertion",
"time": "2023/09/14 07:56:36",
"status": 4
},
{
"feature": "Rename Private Identifiers",
"time": "2023/09/14 07:56:36",
"status": 2
},
{
"feature": "Rename Global Identifiers",
"time": "2023/09/14 07:56:36",
"status": 2
},
{
"feature": "Rename Global Functions",
"time": "2023/09/14 07:56:36",
"status": 1
},
{
"feature": "Rename Private Functions",
"time": "2023/09/14 07:56:36",
"status": 0
},
{
"feature": "AST Executing",
"time": "2023/09/14 07:56:36",
"status": 9
},
{
"feature": "Property Indirection",
"time": "2023/09/14 07:56:36",
"status": 34
},
{
"feature": "Assignment To Function",
"time": "2023/09/14 07:56:36",
"status": 6
},
{
"feature": "Numbers To Expressions",
"time": "2023/09/14 07:56:36",
"status": 9
},
{
"feature": "VM Executing",
"time": "2023/09/14 07:56:36",
"status": 15
},
{
"feature": "Expression To Function",
"time": "2023/09/14 07:56:36",
"status": 30
},
{
"feature": "Boolean Encoding",
"time": "2023/09/14 07:56:36",
"status": 30
},
{
"feature": "Eval Encryption",
"time": "2023/09/14 07:56:36",
"status": 27
},
{
"feature": "Encode Strings",
"time": "2023/09/14 07:56:36",
"status": 33
},
{
"feature": "Control Flow Flattening",
"time": "2023/09/14 07:56:36",
"status": 15
},
{
"feature": "Control Flow Shrinking",
"time": "2023/09/14 07:56:36",
"status": 3
},
{
"feature": "String Array",
"time": "2023/09/14 07:56:36",
"status": 41
},
{
"feature": "String Array Encoding",
"time": "2023/09/14 07:56:36",
"status": 41
},
{
"feature": "AST 2 JavaScript",
"time": "2023/09/14 07:56:36",
"status": 5086
}
]
}
var label = [{"name":"JavaScript"},{"name":"AST"}];
var source = [0];
var target =[1];
var value = [obfuscate_result.status[0].status];
for(i=1; i<obfuscate_result.status.length-1; i++){

label.push({"name":obfuscate_result.status[i].feature + " " + obfuscate_result.status[i].status} );
source.push(1)
target.push(i+1);
if(obfuscate_result.status[i].status == 0){
obfuscate_result.status[i].status =1;
}
value.push(obfuscate_result.status[i].status);
source.push(i+1)
target.push(obfuscate_result.status.length);
value.push(obfuscate_result.status[i].status);
}
label.push({"name":"AST"});
label.push({"name":"ObFuscated JavaScript"});
source.push(label.length-2)
target.push(label.length-1);
value.push(obfuscate_result.status[obfuscate_result.status.length-1].status);
var sankey_data= {}
sankey_data.nodes = label;
sankey_data.links = [];
for(i=0;i<source.length;i++){
sankey_data.links.push({"source":source[i],"target":target[i],"value":value[i]});
}
renderSankey({
el: 'obfuscate_sankey',
layoutStyle: {
width: 1000,
height: 680
},
data: sankey_data
})

</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot - Rest VS GraphQL

文章目录 概述图解CodeSpring Boot RestSpring Boot GraphQL 概述 REST&#xff08;Representational State Transfer&#xff09;和GraphQL都是用于构建Web服务的API设计和交互方式&#xff0c;它们有不同的特点和优劣势。 REST&#xff08;Representational State Transf…

PHP自己的框架2.0加载控制器并运行(重构篇四)

目录 1、加载控制器并运行 2、创建admin和index模块控制器 3、自动加载控制器文件 4、运行控制器中方法 5、运行模块下控制器方法 1、加载控制器并运行 2、创建admin和index模块控制器 <?php namespace app\admin\controller; class index{public function index(){ech…

【pytest】生成测试报告

0. 脚本&#xff1a; fixture/test_fixtures_02.py # 功能函数 import pytestdef multiply(a, b):return a * bclass TestMultiply:# fixturesclassmethoddef setup_class(cls):print("setup_class>")classmethoddef teardown_class(cls):print("teardown_c…

在PHP8中对数组进行计算-PHP8知识详解

在php8中&#xff0c;提供了丰富的计算函数&#xff0c;可以对数组进行计算操作。常见的计算函数如下几个&#xff1a;array_sum()函数、array_merge()函数、array_diff()函数、array_diff_assoc()函数、array_intersect()函数、array_intersect_assoc()函数。 1、array_sum()函…

MySQL数据库——MySQL8.0.26-Linux版安装

目录 准备Linux服务器 下载安装包 上传安装包 创建目录,并解压 安装mysql的安装包 启动MySQL服务 查询自动生成的root用户密码 修改root用户密码 创建用户 并给root用户分配权限 通过DataGrip远程连接MySQL 准备Linux服务器 云服务器或者虚拟机&#xff0c; Linux…

P2P协议的传输艺术

TP 采用两个 TCP 连接来传输一个文件。 控制连接&#xff1a;服务器以被动的方式&#xff0c;打开众所周知用于 FTP 的端口 21&#xff0c;客户端则主动发起连接。该连接将命令从客户端传给服务器&#xff0c;并传回服务器的应答。常用的命令有&#xff1a;list——获取文件目…

图解曲面积分的对称性

1.图解曲面积分的对称性 1.1 第一类曲面积分的一般对称性 二重积分、三重积分、第一类曲线积分、第一类曲面积分的一般对称性其原理都类似 平面和空间曲面的原理一样&#xff0c;以下内容以空间曲面为例 图中所示为积分区域 Σ \Sigma Σ&#xff0c;函数 f ( x , y , z ) f(…

PostgreSQL缓存管理

缓冲区管理器、存储和后端进程之间的关系 缓存管理结构 PostgreSQL 缓冲区管理器由buffer table、buffer descriptors和buffer pool组成。buffer pool层存储表和索引等数据文件页&#xff0c;以及空闲空间映射和可见性映射。buffer pool是一个数组&#xff0c;每个槽存储数据文…

Redis RedLock算法和底层源码分析

Redlock红锁算法 官网地址&#xff1a;Distributed Locks with Redis | Redis 为什么要使用RedLock&#xff1f; 解释&#xff1a; 线程 1 首先获取锁成功&#xff0c;将键值对写入 redis 的 master 节点&#xff0c;在 redis 将该键值对同步到 slave 节点之前&#xff0c;mas…

vue+express、gitee pm2部署轻量服务器

一、代码配置 前后端接口都保持 127.0.0.1:3000 vue创建文件 pm2.config.cjs module.exports {apps: [{name: xin-web, // 应用程序的名称script: npm, // 启动脚本args: run dev, // 启动脚本的参数cwd: /home/vue/xin_web, // Vite 项目的根目录interpreter: none, // 告诉…

java基础-并发编程-CountDownLatch(JDK1.8)源码学习

CountDownLatch方法调用与类关系图 一、初始化&#xff1a;public CountDownLatch(int count) public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync new Sync(count);}Sync(int count) {// 将参数…

pte初步认识学习

我们的时间的确很少&#xff0c;但是我们每天都乐意将珍贵的时间浪费在大量毫无意义的事情上 目录 pte介绍 PTE口语评分规则 pte架构 计算机科学23 QS排名 《芭比》 pte介绍 PTE口语评分规则 有抑扬顿挫 对于连读 不能回读 native pte对于个别单词没有读好&#xff0c…

JSP 学习笔记(基础)

出现背景&#xff1a; 由于 Servlet 输出 HTML 比较困难&#xff0c;所以出现了 JSP 这个代替品。 特点&#xff1a; 基于文本&#xff0c;HTML 和 Java 代码共同存在&#xff08;用 write() 来写 HTML 标签&#xff09;其本身就是个被封装后的 Servlet&#xff08;被编译为…

JavaScript的BOM操作

一、BOM 1.认识BOM BOM&#xff1a;浏览器对象模型&#xff08;Browser Object Model&#xff09; 简称 BOM&#xff0c;由浏览器提供的用于处理文档&#xff08;document&#xff09;之外的所有内容的其他对象&#xff1b;比如navigator、location、history等对象&#xff…

Android 使用Camera1实现相机预览、拍照、录像

1. 前言 本文介绍如何从零开始&#xff0c;在Android中实现Camera1的接入&#xff0c;并在文末提供Camera1Manager工具类&#xff0c;可以用于快速接入Camera1。 Android Camera1 API虽然已经被Google废弃&#xff0c;但有些场景下不得不使用。 并且Camera1返回的帧数据是NV21…

JSP ssm 零配件管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java ssm 零配件管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用…

ThinkPHP 5.0通过composer升级到5.1,超级简单

事情是这样的&#xff0c;我实现一个验证码登录的功能&#xff0c;但是这个验证码的包提示tp5的版本可以是5.1.1、5.1.2、5.1.3。但我使用的是5.0&#xff0c;既然这样&#xff0c;那就升个级呗&#xff0c;百度了一下&#xff0c;结果发现大部分都是讲先备份application和修改…

python之pyQt5实例:PyQtGraph的应用

1、显示逻辑 "MainWindow": "这是主窗口&#xff0c;所有的其他组件都会被添加到这个窗口上。", "centralwidget": "这是主窗口的中心部件&#xff0c;它包含了其他的部件。","pushButton": "这是一个按钮&#xff0c…

算法刷题 week3

这里写目录标题 1.重建二叉树题目题解(递归) O(n) 2.二叉树的下一个节点题目题解(模拟) O(h) 3.用两个栈实现队列题目题解(栈&#xff0c;队列) O(n) 1.重建二叉树 题目 题解 (递归) O(n) 递归建立整棵二叉树&#xff1a;先递归创建左右子树&#xff0c;然后创建根节点&…

贪心算法的思路和典型例题

一、贪心算法的思想 贪心算法是一种求解问题时&#xff0c;总是做出在当前看来是最好的选择&#xff0c;不从整体最优上加以考虑的算法。 二.用贪心算法的解题策略 其基本思路是从问题的某一个初始解出发一步一步地进行&#xff0c;根据某个优化测度&#xff0c;每一步都要确保…