GithubHelp home page GithubHelp logo

xswei / d3js_doc Goto Github PK

View Code? Open in Web Editor NEW
1.9K 49.0 341.0 8.45 MB

D3js中文文档 D3中文 :bar_chart: :chart_with_upwards_trend: :tada:

Home Page: https://d3js.org.cn/

HTML 99.79% CSS 0.21%
d3 d3js d3v4 d3v5

d3js_doc's Introduction

GitHub stars GitHub issues GitHub forks GitHub last commit

D3: Data-Driven Documents

D3 (或者叫 D3.js )是一个基于 web 标准的 JavaScript 可视化库。 D3 可以借助 SVG, Canvas 以及 HTML 将你的数据生动的展现出来。 D3 结合了强大的可视化交互技术以及数据驱动 DOM 的技术,让你可以借助于现代浏览器的强大功能自由的对数据进行可视化。


资源

文档

示例

社区

教程

安装

如果使用 npm,则可以通过 npm install d3 来安装。 此外还可以下载 最新版, 最新版支持 AMDCommonJS 以及基础标签引入形式。 你也可以直接从 d3js.orgCDNJS, 或者 unpkg 加载. 比如:

<script src="https://d3js.org/d3.v6.js"></script>

压缩版:

<script src="https://d3js.org/d3.v5.min.js"></script>

你也可以单独使用 d3 中的某个模块, 比如单独使用 d3-selection

<script src="https://d3js.org/d3-selection.v1.js"></script>

D3基于 ES2015 modules 开发。 可以使用 Rollupwebpack 或者其他你偏爱的打包工具进行构建。 在一个符合 ES2015 的应用中导入 d3 或者 d3 的某些模块:

import { scaleLinear } from "d3-scale";

或者导入 d3 的全部功能并且设置命名空间 (这里是 d3):

import * as d3 from "d3";

Nodejs 环境中:

var d3 = require("d3");

你也可以导入多个模块然后将这些模块集合到 d3 对象中, 此时使用 Object.assign

var d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection"));

支持环境

D3 5.0 支持最新浏览器,比如 ChromeEdgeFirefox 以及 SafariD3 v4 以及之前的版本支持 IE 9 以上的版本。D3 的一部分功能能在旧版的浏览器中运行,因为 D3 的核心功能对浏览器的要求比较低。例如 d3-selection 使用 Level 1Selectors API,但是可以通过预先加载 Sizzle 来实现兼容。现代浏览器对 SVGCSS3 Transition 的支持比较好。所以 D3 不支持更低级别的浏览器,如果你的浏览器不支持这些标准,那么对不起了,大兄弟。

D3 也可以运行在 NodeWeb workers 中. 在 Node 环境中使用 DOM 的时候,必须要提供自己的 DOM 实现。推荐使用 JSDOM,为了避免定义全局 document,建议将 DOM 传递给 d3.select 或者将 NodeList 传递给 d3.selectAll,如下:

var d3 = require("d3"),
    jsdom = require("jsdom");

var document = jsdom.jsdom(),
    svg = d3.select(document.body).append("svg");

在支持 ES 模块化 的环境中,你可以将 d3 作为一个命名空间来导入 D3 的全部功能:

import * as d3 from "d3";

如果你不想导入全部模块,则分配命名空间的时候要和 d3 进行区分:

import * as d3 from "d3";
import * as d3GeoProjection from "d3-geo-projection";

出于这个原因,应该优先考虑 D3 模块中的原有变量名,可以按需导入:

import {select, selectAll} from "d3-selection";
import {geoPath} from "d3-geo";
import {geoPatterson} from "d3-geo-projection";

如果你使用打包工具,则确保已经配置好正确的入口,可以参考 resolve.mainFields

Changes in D3 6.0

2020.08.26发布

这个文档只包含主要更新。 次要更新以及修订请参阅 发布记录.

D3 现在 采用原生集合 (Map 和 Set) 并且 接受迭代d3.group 和 d3.rollup 是强大的用来替代 d3.nest 的聚合函数,并且能与 d3-hierarchy 以及 d3-selection 很好的结合。在 d3-array 中也新增了很多辅助工具,比如 d3.greatestd3.quickselect,以及 d3.fsum.

D3 现在 直接将事件传递给监听器,替代了全局 d3.event 并将 D3 与普通 JavaScript 和大多数其他框架内联。

d3-delaunay (基于 Vladimir Agafonkin 的 Delaunator) 替代了 d3-voronoi, 获得了极大的性能提升,鲁棒性以及 搜索。新的 d3-geo-voronoi 可以用于球面地理数据计算! d3-random 进行了 极大的扩展 并且包含了快速 线性同余生成器 用于随机性。 d3-chord 包含了新的布局以用于 有向 和转置弦图。 d3-scale 新增了径向缩放 类型。

… 以及其他各种小的改进。 超过 450 个例子 已经升级到 D3 6.0!

d3-array

参考 https://observablehq.com/@d3/d3-array-2-0 获取更多详情.

d3-brush

d3-chord

d3-delaunay

d3-drag

  • drag.on 直接传递 event 给监听器.

d3-force

  • simulation.tick 新增 iterations 参数.
  • 新增 forceCenter.strength.
  • 新增 forceSimulation.randomSource.
  • 所有内置的力模型现在都是完全确定的 (包括“抖动的”重合节点).
  • 通过半径的偏移来改进默认的 phyllotaxis 布局.
  • 改进边引用未知节点时的错误消息.
  • force.initialize 被改为传递一个随机的源.
  • 修复初始化位置固定的节点的缺陷.

d3-format

  • 将默认的负号改为负号 (−) 而不是连字减号 (-).
  • 修正大于或等于 1e21 的数字的十进制格式 d.

d3-geo

  • 修复一些退化多边形的裁剪.

d3-hierarchy

d3-interpolate

d3-quadtree

  • 修正了坐标偏离到巨大值时的无限循环.

d3-random

感谢 @Lange, @p-v-d-Veeken, @svanschooten, @Parcly-Taxel 和 @jrus 的贡献s!

d3-scale

d3-selection

  • 新增 selection.selectChild.
  • 新增 selection.selectChildren.
  • 新增 d3.pointer.
  • 新增 d3.pointers.
  • 新增 selection[Symbol.iterator]; selections are now iterable!
  • selection.data 接受迭代.
  • d3.selectAll 接受迭代.
  • selection.on 被修改为直接传递 event 给监听器.
  • selection.on 监听器中移除索引和组!
  • 移除 d3.event!
  • 移除 d3.mouse.
  • 移除 d3.touch.
  • 移除 d3.touches.
  • 移除 d3.customEvent.
  • 移除 d3.clientPoint.
  • 移除 d3.sourceEvent.
  • 修复了 selection.merge(transition) 报错问题.

所有的修改请参考 https://observablehq.com/@d3/d3-selection-2-0.

d3-shape

  • 接受迭代.
  • 新增 d3.line(x, y) 速写.
  • 新增 d3.area(x, y0, y1) 速写.
  • 新增 d3.symbol(type, size) 速写.

d3-time-format

  • 新增 ISO 8601 “week year” (%G and %g).

d3-timer

d3-transition

d3-zoom

  • 新增 zoom.tapDistance.
  • zoom.on 直接传递 event 给监听器.
  • 修改默认的 zoom.filter 如果按下控制键,过滤器观察 wheel 事件.
  • 修改默认的 zoom.wheelDelta 如果按下控制键,缩放更快.
  • 不要设置触控动作:无.
  • 升级到 d3-selection 2.

Breaking Changes

D3 6.0 包含了一些非向后兼容的改变.

D3 现在需要运行在支持 ES2015 的浏览器上. 对于不支持的浏览器,你需要自己做转义.

最后, 对 Bower 的支持被取消了; D3 现在只在 npm 和 GitHub 上发布.

参考我们的 升级指南 获取升级帮助.

5.x.x 大版本改动

D3 5.0 引入了很少的非向后兼容的改变。

D3 5.0 现在采用的是 Promises 来替代异步回调加载数据。 Promises 简化了异步代码结构,尤其是现代浏览器支持 async 和 await 操作。(在 Observable 中参考 promises 介绍)。例如在 V4 中使用如下方式加载 CSV 文件:

d3.csv("file.csv", function(error, data) {
  if (error) throw error;
  console.log(data);
});

V5 中基于 Promises 实现:

d3.csv("file.csv").then(function(data) {
  console.log(data);
});

要注意的是不需要重新抛出错误,因为 Promise 会自动 reject,并且需要的话可以使用 promise.catch。使用 await 的话代码会更简单:

const data = await d3.csv("file.csv");
console.log(data);

由于采用了 promisesD3 5.0 使用 Fetch API 来代替 XMLHttpRequestd3-request 模块由 d3-fetch 替代。Fetch 支持许多强大的特性,比如 响应流D3 5.0 也不再使用 d3-queue,取而代之推荐 Promise.all 来处理批量异步任务,或者使用辅助库比如 p-queue 来 控制并发

D3 5.0 不再提供 d3.schemeCategory20* 颜色方案。因为这些颜色有缺陷,可能会错误的暗示数据中的关系:色调相近的可能被认为是一个分组,而亮度可能被错认为是排序。作为替换,D3 5.0 使用 d3-scale-chromatic,它实现了 ColorBrewer 的方案设计,包括 categoricaldivergingsequential single-huesequential multi-hue 方案。这些颜色方案在连续式和分散式都是可用的。

D3 5.0 提供了通过 d3-contour 实现的 marching squares(生成二维轮廓的算法)density estimation(密度估计). 并且添加了两个新的 d3-selection  方法:selection.clone 用来克隆已选择的节点,d3.create 用来创建分离的元素。 Geographic projections 也支持  projection.angle,一种由 Philippe Rivière 提出的梦幻般的新的多面体投影。

最后,D3 5.0package.json 不再引用依赖的精确版本,解决了重复安装 D3 模块的问题。

本地开发

由于浏览器的安全策略,不能直接读取本地文件。在本地开发的时候,必须要运行一个服务器环境而不是使用 file://, 推荐使用 Nodejshttp-server,安装方法:

npm install -g http-server

运行:

http-server & 

然后会在当前目录启动一个 http://localhost:8080 的服务。

营养跟不上了快给我来瓶冰阔乐

翻译说明

每个子仓库中包含三个 .md 文件:

  • README.md 文件是翻译后的中文版
  • README_EN.md 文件是翻译时参照的英文版
  • README_ORIGIN.md 文件是源仓库文档

更新时,首先将 README_ORIGIN.md 与官网文档进行同步,然后将 README_EN.mdREADME_ORIGIN.md 进行比对, 将 diff 更新至 README.md,同时将 README_EN.md 与 README_ORIGIN.md 进行同步。

版权说明

Creative Commons License

star 趋势

Stargazers over time

d3js_doc's People

Contributors

dodio avatar liuyiliuyi avatar njueyupeng avatar xswei avatar yky5188 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3js_doc's Issues

d3.js

请问下 是v5版本吗,感谢大佬的示例,希望继续维护

翻译(“因此使用了d3-format进行了格式化。”)不准确。

d3.ticks() 部分,“由于小数可能并不精确,因此使用了d3-format进行了格式化。”不准确。“因此”应改为“可以”。从源码也可以看出,并未使用 d3-format 进行格式化。现在的翻译让人产生误解,认为 d3-array 依赖于 d3-format 。

the returned value may not be exact decimals; use d3-format to format numbers for human consumption.

README.md - 文字修正

如果要使用某个固定的版本,则考虑CNDJS 或 unpkg

中間的CNDJS要改成 CDNJS

P.S. 這只是個小問題 QQ

D3-v4 或 v5 力导向图更新节点时出现多余的节点问题!

力导向试图中更新节点时出现重复元素的节点,见图所示!
错误节点

`

<title>知识图谱</title> <style type="text/css">
.active{
    stroke:#333333;
    stroke-width:2px;
}
circle {
  fill: #CCCCCC;
  stroke: #333333;
  stroke-width: 1px;
}
text {
  font-size: 12px;
  pointer-events: none;
  text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
.layui-card {border:1px solid #f2f2f2;border-radius:5px;}
.icon {margin-right:10px;color:#1aa094;}
.icon-cray {color:#ffb800!important;}
.icon-blue {color:#1e9fff!important;}
.icon-tip {color:#ff5722!important;}
.layuimini-qiuck-module a i {display:inline-block;width:100%;height:60px;line-height:60px;text-align:center;border-radius:2px;font-size:30px;background-color:#F8F8F8;color:#333;transition:all .3s;-webkit-transition:all .3s;}
.layuimini-qiuck-module a cite {position:relative;top:2px;display:block;color:#666;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;font-size:14px;}
.main_btn > p {height:40px;}
</style>
搜索
标签 / 规则
公用系统 发电机 清空 测试数据
                        </div>
                    </div>
                </div>
                <div class="layui-col-md12">
                    <div class="layui-card">
                        <div class="layui-card-header">
                            <i class="fa fa-share-alt icon icon-cray"></i>可视化展示
                            <ul class="layui-layout-right" style="margin-right: 10px;">
                                <button type="button" class="layui-btn layui-btn-primary  layui-btn-radius layui-btn-xs paigusu">BigSystem</button>
                                <button type="button" class="layui-btn layui-btn-primary  layui-btn-radius layui-btn-xs paigusu">Equipment</button>
                                <button type="button" class="layui-btn layui-btn-primary  layui-btn-radius layui-btn-xs paigusu">Symptom</button>
                                <button type="button" class="layui-btn layui-btn-primary  layui-btn-radius layui-btn-xs paigusu">Crew</button>
                            </ul>
                        </div>
                        <div class="layui-card-body">
                            <div id="graph"></div>
                        </div>
                        <div style="border-bottom:1px solid #f6f6f6;color:#333;"></div>
                        <div style="height:32px;line-height:32px;padding:0 15px;" id="nodeMessage">

                        </div>
                    </div>
                </div>
                <div class="layui-col-md7">
                    <div class="layui-card">
                        <div class="layui-card-header">
                            <i class="fa fa-bar-chart icon icon-blue"></i>图形展示
                            {% comment %}<ul class="layui-layout-right">
                                <i class="fa fa-bar-chart icon icon-blue" title="柱状图" style="cursor:pointer;"></i>
                                <i class="fa fa-line-chart icon icon-blue" title="折线图" style="cursor:pointer;"></i>
                                <i class="fa fa-pie-chart icon icon-blue" title="饼状图" style="cursor:pointer;"></i>
                            </ul>{% endcomment %}
                        </div>
                        <div class="layui-card-body">
                            <div id="echarts_view" style="width: 100%;min-height:200px"></div>
                        </div>
                    </div>
                </div>
                <div class="layui-col-md5">
                    <div class="layui-card">
                        <div class="layui-card-header"><i class="fa fa-share-alt icon"></i>数据展示</div>
                        <div class="layui-card-body">
                            <div style="width: 100%;min-height:200px" id="dataMessage">

                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</div>
<script src="/static/js/d3.v5.min.js" charset="utf-8"></script> <script src="/static/js/echarts-4.5.0.js" charset="utf-8"></script> <script src="/static/lib/jquery-3.4.1/jquery-3.4.1.min.js" charset="utf-8"></script> <script src="/static/js/paigusu.min.js"></script> <script>
function testsGraphs(){
    let init_label=[{type:"BigSystem"},{type:"Equipment"}];
    let news_label=[{type:"BigSystem"},{type:"Crew"},{type:"Equipment"}];
    let arr_c = init_label.concat(news_label);
    let result = [];
    for (let i = 0; i < arr_c.length; i++) {
        let flag = true;
        let temp = arr_c[i];
        for (let j = 0; j < result.length; j++) {
            // 普通数组 (temp === result[j])
            if (temp.type === result[j].type) {
                flag = false;
                break;
            }
        }
        if (flag) {
            result.push(temp);
        }
    }

    let myJson = {"name": "phpernote", "password": "1111","index":"0"};
    for (let val in myJson) {
        if(val!="index")
            alert(val + " " + myJson[val]);//输出如:name
    }
}
// 颜色选择器
$('.paigusu').paigusu({
    color : '#1926dc',//初始色  支持两种配置方案
},function(event,obj){
	console.log(event);
	console.log(obj);
	$(event).css('background-color','#' + obj.hex);
	let c = $(event).text();
    $("."+c).css("fill",'#' + obj.hex);
});

var width = $("#graph").width();
var height = 400;
var nodes = [];         // 节点数据
var links = [];         // 变关系数据
var svg;
var simulation;
var marker;
var svg_links;
var edge_text;
var svg_nodes;
var svg_texts;
var lineTextFontSize = 12;
var circle_radius = 23;
//var color = d3.scaleOrdinal(d3.schemeCategory20);
var links_group;  // 线边层
var nodes_group;  // 节点层
var nodeConfig = []; //标签样色,数量配置

// 绘制节点
function drawNodes(){
    svg_nodes = nodes_group.selectAll("circle")
        .data(nodes)
        .enter()
        .append("circle")
        .attr("r", circle_radius)
        .attr("class", function (d) {
            return d.type;
        })
        .style("fill", function (d, i) {
            if(d.type == 'BigSystem'){
                return "#00C5CD";
            }else if(d.type == 'Equipment'){
                return "#9BCD9B";
            }else{
                return "#EEDC82";
            }if(d.type== 'Symptom'){
                return "#EEDC82";
            }else{
                return "#CDCDB4";
            }
        })
        .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended))//创建一个拖拽行为
        .on("click",function(node){
            //单击时让连接线加粗
            svg_links.style("stroke-width",function(line){
                if(line.source.name==node.name || line.target.name==node.name){return 4;}else{return 2;}
            });
        })
        .on("mouseover", function (d, i) {
            d3.select(this).classed('active', true);
            let htmls = nodesMessage(d);
            $("#nodeMessage").html(htmls);
        }).on("mouseout", function (d, i) {
            d3.select(this).classed('active', false);
            $("#nodeMessage").html('<span style="color:#666666">总计:节点'+nodes.length+'个,关系边:' + links.length + '条');
        }).on("dblclick", function(d, i){
            expsGraphs(d.type, d.pk);
        });
}
// 绘制节点描述文字
function drawNodesText(){
    svg_texts =  nodes_group
        .selectAll("text")
        .data(nodes)
        .enter()
        .append("text")
        .style("fill", "black")
        .attr("dominant-baseline","middle")
        .attr("text-anchor", "middle")
        .text(function (d) {
            if(d.name.length > 3){
                return d.name.substring(0,3) + "\n" + "..";
            }else{
                return d.name;
            }
        });
}
// 绘制节点之间的连接线
function drawLinks(){
    svg_links = links_group.selectAll(".edgepath")
        .data(links)
        .enter()
        .append("path")
        .attr('class','edgepath')
        .attr('id',function(d,i) {return 'edgepath'+i;})
        .style("stroke",'#ccc')
        .style("pointer-events", "none")
        .style("stroke-width",2);  //线条粗细
}
// 绘制连接线描述文字
function drawLinksText(){
    edge_text = links_group.selectAll(".edgelabel")
        .data(links)
        .enter()
        .append("text")
        .style('font-size', lineTextFontSize)
        .style("pointer-events", "none")
        .attr('class','edgelabel')
        .attr('id',function(d,i){return 'edgepath'+i;})
        .attr('dx',30)
        .attr('dy',0)
        .append('textPath')
        .attr('xlink:href',function(d,i) {return '#edgepath'+i})
        .style("pointer-events", "none")
        .text(function(d){return '同事';});
}
// 绘制连接线箭头
function drawMarker(){
    marker = svg.append("marker")
        .attr("id", "resolved")
        .attr("markerUnits","userSpaceOnUse")
        .attr("viewBox", "0 -5 10 10")//坐标系的区域
        .attr("refX",28)//箭头坐标
        .attr("refY", 0)
        .attr("markerWidth", 12)//标识的大小
        .attr("markerHeight", 12)
        .attr("orient", "auto")//绘制方向,可设定为:auto(自动确认方向)和 角度值
        .attr("stroke-width",1)//箭头宽度
        .append("path")
        .attr("d", "M0,-5L10,0L0,5")//箭头的路径
        .attr('fill','#CCCCCC');//箭头颜色
}
// 绘制力导向图
function drawsGraphs(label,name){
    clearGraphs();
    $.ajax({
        url: "/ResModel/find_nodes",
        type: "POST",
        dataType: "JSON",
        data:{"label":label,"name":name},
        async: false,       // false 为同步, true 为异步
        success: function(data) {
            for (let i=0;i<data.length;i++) {
                nodes.push(data[i]);
            }
        },
        //请求失败,包含具体的错误信息
        error : function(e) {
            console.log(e.status);
            console.log(e.responseText);
        }
    });
    createSVG();    //创建 SVG 图层
    //设置SVG大小并且创建缩放行为和设置缩放范围
    svg.attr("width", width).attr("height", height).call(d3.zoom().scaleExtent([1, 1]).on('zoom',zoom_actions));
    //初始化力学仿真器,通过布局函数格式化数据
    simulation = d3.forceSimulation(nodes)
        .force("link", d3.forceLink(links).distance(120))           //distance设置连线距离
        .force("charge", d3.forceManyBody().strength(-50))
        .force("center", d3.forceCenter(width / 2 - 200, height / 2)).on("tick", ticked);    //设置力学仿真器的中心
    // 绘制节点
    drawNodes();
    //绘制节点描述文字
    drawNodesText();
    // 绘制连线
    drawLinks();
    // 绘制连线文字
    drawLinksText();
    // 绘制连接线箭头
    drawMarker();
}
// 双击节点展开关联节点
function expsGraphs(label, id){
    $.ajax({
        url: "/ResModel/exps_nodes",
            type: "POST",
            dataType: "JSON",
            data:{
                "label":label,
                "id":id
            },
            async: true,       // false 为同步, true 为异步
            success: function(data) {
                let dataNodes = data.nodes;
                let dataLinks = data.links;
                let jsonLinks = filterLinks(links,dataLinks);   //过滤关系连接线边
                let jsonNodes = filterNodes(nodes,dataNodes);   //过滤节点
                // 为节点添加位置信息以供links使用
                let nodesSize = nodes.length;
                for (let i=0;i<jsonNodes.length;i++){
                    jsonNodes[i].maps = nodesSize + i;
                    nodes.push(jsonNodes[i]);
                }
                for (let k=0;k<jsonLinks.length;k++){
                    for (let j=0;j<nodes.length;j++) {
                        if(jsonLinks[k].s_node == nodes[j].pk){
                            jsonLinks[k].source = nodes[j].maps;
                        }
                        if(jsonLinks[k].e_node == nodes[j].pk){
                            jsonLinks[k].target = nodes[j].maps;
                        }
                    }
                    links.push(jsonLinks[k]);
                }
                $("#dataMessage").text(JSON.stringify(nodes));
                updateGraphs();
            },
            //请求失败,包含具体的错误信息
            error : function(e) {
                console.log(e.status);
                console.log(e.responseText);
            }
        });
}
// 更新力导向图
function updateGraphs(){
     svg_nodes = svg_nodes
        .data(nodes, (d) => d.name)
        .enter()
        .append("circle")
        .attr("r",circle_radius)
        .attr("class", function (d) {
            return d.type;
        })
        .style("fill", function (d, i) {
            if(d.type == 'BigSystem'){
                return "#00C5CD";
            }else if(d.type == 'Equipment'){
                return "#9BCD9B";
            }else if(d.type== 'Symptom'){
                return "#EEDC82";
            }else{
                return "#CDCDB4";
            }})
        .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended))
         .merge(svg_nodes)
        .on("click",function(node){
            //单击时让连接线加粗
            svg_links.style("stroke-width",function(line){
                if(line.source.pk==node.pk || line.target.pk==node.pk){return 4;}else{return 2;}
            });
        })
        .on("mouseover", function (d, i) {
            d3.select(this).classed('active', true);
            let htmls = nodesMessage(d);
            $("#nodeMessage").html(htmls);
        }).on("mouseout", function (d, i) {
            d3.select(this).classed('active', false);
            $("#nodeMessage").html('<span style="color:#666666">总计:节点'+nodes.length+'个,关系边:' + links.length + '条');
        }).on("dblclick", function(d, i){
            expsGraphs(d.type, d.pk);
        });
    svg_texts = svg_texts.data(nodes)
        .enter()
        .append("text")
        .style("fill", "black")
        .attr("dominant-baseline","middle")
        .attr("text-anchor", "middle")
        .text(function(d){
            if(d.name.length > 3){
                return d.name.substring(0,3) + "..";
            }else{
                return d.name;
            }})
        .merge(svg_texts);
    svg_links = svg_links.data(links, (d) => {return d.source.name + "-" + d.target.name; })
        .enter()
        .append("path")
        .style("stroke","#ccc")
        .attr('class','edgepath')
        .attr('id',function(d,i) {return 'edgepath'+i;})
        .style("pointer-events", "none")
        .style("stroke-width",2)
        .merge(svg_links);
    edge_text = edge_text.data(links)
        .enter()
        .append("text")
        .style("pointer-events", "none")
        .attr('class','edgelabel')
        .attr('id',function(d,i){return 'edgepath'+i;})
        .attr('dx',30)
        .attr('dy',0)
        .append('textPath')
        .attr('xlink:href',function(d,i) {return '#edgepath'+i})
        .text(function(d){
            if(d.type.length > 4){
                return d.type.substring(0,4) + "..";
            }else{
                return d.type;
            }})
        .merge(edge_text);
    simulation.nodes(nodes);
    simulation.force("link").links(links);
    simulation.alpha(1).restart();
}
// 清空力导向图
function clearGraphs(){
    links = [];
    nodes = [];
    d3.selectAll("svg").remove();
    $("#nodeMessage").text('');
}
// 过滤节点对象,取差集
function filterNodes(init_arr,data_arr) {
    let clone = data_arr.slice(0);
    for (let i = 0; i < init_arr.length; i++) {
        let temp = init_arr[i];
        for (let j = 0; j < clone.length; j++) {
            // 普通数组 (temp === clone[j])
            if (temp.pk === clone[j].pk) {
                clone.splice(j, 1);
            }
        }
    }
    return clone;
}
// 过滤边对象,取差集
function filterLinks(init_arr,data_arr) {
    let clone = data_arr.slice(0);
    for (let i = 0; i < init_arr.length; i++) {
        let temp = init_arr[i];
        for (let j = 0; j < clone.length; j++) {
            // 普通数组 (temp === clone[j])
            if (temp.pk === clone[j].pk) {
                clone.splice(j, 1);
            }
        }
    }
    return clone;
}
// 鼠标移动节点信息
function nodesMessage(d){
    let htmls = '<button type="button" class="layui-btn layui-btn-primary  layui-btn-radius layui-btn-xs ">' + d.type +
                '</button> &nbsp;&nbsp;' +
                '<span style="color:#666666">';
    for (var val in d){
        if(val != 'index' && val != 'x' && val != 'y'
            && val != 'vx' && val != 'vy' && val != 'maps' && val != 'fy' && val != 'fx'){
            htmls +=  "[" + val + "]:" + d[val]+"&nbsp;&nbsp;";
        }
    }
    htmls = htmls + '</span>';
    return htmls;
}
// 创建 SVG 图层
function createSVG(){
    svg = d3.select("#graph").append("svg");
    links_group = svg.append('g');  // 线边层
    nodes_group = svg.append('g');  // 节点层
}
 //监听拖拽开始
function dragstarted(d) {
    if (!d3.event.active){
        simulation.alphaTarget(0.8).restart(); //alpha是动画的冷却系数,运动过程中会不断减小,直到小于0.005为止,此时动画会停止。
    }
    d.fx = d.x;    //fx为固定坐标,x为初始坐标  注3>
    d.fy = d.y;
}
//监听拖拽中
function dragged(d) {
    d.fx = d3.event.x;  //fevent.x为拖拽移动时的坐标
    d.fy = d3.event.y;
}
//监听拖拽结束
function dragended(d) {
    if (!d3.event.active)
        simulation.alphaTarget(0);
    d.fx = null;        //固定坐标清空
    d.fy = null;
}
//拖拽时的事件监听器  以实时更新坐标
function ticked() {
    svg_nodes
        .attr("cx",function(d){return d.x;})
        .attr("cy",function(d){return d.y;})
    svg_texts
        .attr("x", function(d){ return d.x; })
        .attr("y", function(d){ return d.y; });
    svg_links
        .attr("d",function(d){
            return 'M '+ d.source.x +' '+d.source.y+' L '+ d.target.x +' '+d.target.y
        })
        .attr("marker-end", "url(#resolved)");
}
//比例缩放和拖动
function zoom_actions() {
    var transform = d3.event.transform;
    svg_nodes.attr('transform', transform);
    svg_texts.attr("transform",transform);
    svg_links.attr("transform",transform);
}

//图形展示
var echarts_view = echarts.init(document.getElementById('echarts_view'));
var optionRecords = {
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data:['检修(大)','检修(小)','日常维护']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    toolbox : {
        show : true,
        feature : {
            magicType : {
                show : true,
                type : [ 'line', 'bar' ]
            },
            restore : {
                show : true
            },
            saveAsImage : {
                show : true,
                title : '保存为图片',
                type : 'png',
                lang : [ '点击保存' ]
            }
        }
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['阀门','泵','电气','燃料堆','反应堆','蒸汽','隔离区']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name:'检修(大)',
            type:'line',
            data:[10, 10, 10, 10, 15, 15, 20]
        },
        {
            name:'检修(小)',
            type:'line',
            data:[4, 4, 6, 4, 3, 3, 4]
        },
        {
            name:'日常维护',
            type:'line',
            data:[20, 50, 30, 40, 10, 30, 50]
        }
    ]
};
echarts_view.setOption(optionRecords);
//echarts 窗口缩放自适应
window.onresize = function(){
    echartsRecords.resize();
}
</script> `

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.