欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

D3js(三):force实例

发布时间:2024/9/15 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 D3js(三):force实例 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

文章目录

  • Data-Driven Documents理解
    • selections
      • selections操作
  • 直接上码:
    • 导入库,这里使用d3.v3,d3.v5可能有差异:
    • 建立画布,并把画布svg添加到html的body或者div里
    • 建立力矩图
    • 读取json数据
    • 把数据放进force里,force就可以直接使用自己的数据了
    • 依次把边添加到svg
    • 依次把节点添加到svg
    • 定义事件 mouseover, mouseout
    • 定义事件 tick
    • 拖拽固定
    • zoom
  • 完整code:

Data-Driven Documents理解

首先它是js,js本质就是dom(Document Object Model,简称DOM)的增删查改,dom的本质就是一棵树,d3本质也是对一棵树进行操作。

selections

对dom操作,最开始就是定位,也就是选择哪一块,哪一颗子树

d3.selectAll("p").style("color", "blue");

selections操作

// Update… var p = d3.select("body").selectAll("p").data([4, 8, 15, 16, 23, 42]).text(function(d) { return d; });// Enter… p.enter().append("p").text(function(d) { return d; });// Exit… p.exit().remove();

直接上码:

导入库,这里使用d3.v3,d3.v5可能有差异:

<script src="http://d3js.org/d3.v3.min.js"></script>

建立画布,并把画布svg添加到html的body或者div里

var width = 960,height = 960var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);

建立力矩图

var force = d3.layout.force().gravity(.05).charge(-240).linkDistance(160).size([width, height]);

读取json数据

d3.json("graph.json", function(error, json) {if (error) throw error;}

把数据放进force里,force就可以直接使用自己的数据了

force.nodes(json.nodes).links(json.links).start();

依次把边添加到svg

selectAll(".link")相当于占位符,添加"line"标签,设置该line标签的属性

var link = svg.selectAll(".link").data(json.links).enter().append("line").attr("class", "link").attr("stroke-width", function(d) { return Math.sqrt(d.value); });

依次把节点添加到svg

节点包括node和text两部分,使用group包起来,先添加g标签再添加circle和text标签

var node = svg.selectAll(".node").data(json.nodes).enter().append('g').attr("class", "node").style("fill","red").on("mouseover", mouseover).on("mouseout", mouseout).call(force.drag);node.append("circle").attr("r", 8);node.append("text").attr("dy", ".35em").text(function(d) { return d.name; });

定义事件 mouseover, mouseout

mouseover, mouseout为基本事件
transition变换过渡效果

function mouseover() {d3.select(this).select("circle").transition().duration(750).attr("r", 80);}function mouseout() {d3.select(this).select("circle").transition().duration(750).attr("r", 8);}

定义事件 tick

实际就是补充div的属性

force.on("tick", tick);function tick() {link.attr("x1", function(d) { return d.source.x; }).attr("y1", function(d) { return d.source.y; }).attr("x2", function(d) { return d.target.x; }).attr("y2", function(d) { return d.target.y; });node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });};

拖拽固定

相当于重写了drag函数

var node_drag = d3.behavior.drag().on("dragstart", dragstart).on("drag", dragmove).on("dragend", dragend);var node = svg.selectAll(".node").data(json.nodes).enter().append('g').attr("class", "node").style("fill","red").on("mouseover", mouseover).on("mouseout", mouseout)//.call(force.drag);.call(node_drag);function dragstart(d, i) {force.stop() // stops the force auto positioning before you start dragging}function dragmove(d, i) {d.px += d3.event.dx;d.py += d3.event.dy;d.x += d3.event.dx;d.y += d3.event.dy;tick(); // this is the key to make it work together with updating both px,py,x,y on d !}function dragend(d, i) {d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stufftick();force.resume();}

zoom

var zoom = d3.behavior.zoom().scaleExtent([1, 10]).on("zoom", zoomed);var svg = d3.select("body").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.right + ")").call(zoom);//specify what to do when zoom event listener is triggeredfunction zoomed() {g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");}

完整code:

<!DOCTYPE html> <meta charset="utf-8"> <style>.link {stroke: #777;stroke-opacity: 0.5;}</style> <body><script src="http://d3js.org/d3.v3.min.js"></script> <script>d3.json("graph.json", function(error, json) {if (error) throw error;var margin = {top: -5, right: -5, bottom: -5, left: -5},width = 960 - margin.left - margin.right,height = 960 - margin.top - margin.bottom;var zoom = d3.behavior.zoom().scaleExtent([1, 10]).on("zoom", zoomed);var svg = d3.select("body").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.right + ")").call(zoom);var force = d3.layout.force().gravity(.05).charge(-240).linkDistance(160).size([width, height]);force.nodes(json.nodes).links(json.links).start();var g = svg.append("g").attr("class", "everything");var link = g.append("g").attr("class", "links").selectAll(".link").data(json.links).enter().append("line").attr("class", "link").attr("stroke-width", function(d) { return Math.sqrt(d.value); });// var node_drag = d3.behavior.drag()// .on("dragstart", dragstart)// .on("drag", dragmove)// .on("dragend", dragend);var node = g.append("g").attr("class", "nodes").selectAll(".node").data(json.nodes).enter().append('g').attr("class", "node").style("fill","red").on("mouseover", mouseover).on("mouseout", mouseout).call(force.drag);//.call(node_drag);node.append("circle").attr("r", 8);node.append("text").attr("dy", ".35em").text(function(d) { return d.name; });force.on("tick", tick);function tick() {link.attr("x1", function(d) { return d.source.x; }).attr("y1", function(d) { return d.source.y; }).attr("x2", function(d) { return d.target.x; }).attr("y2", function(d) { return d.target.y; });node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });};function mouseover() {d3.select(this).select("circle").transition().duration(750).attr("r", 80);}function mouseout() {d3.select(this).select("circle").transition().duration(750).attr("r", 8);}// function dragstart(d, i) {// force.stop() // stops the force auto positioning before you start dragging// }//// function dragmove(d, i) {// d.px += d3.event.dx;// d.py += d3.event.dy;// d.x += d3.event.dx;// d.y += d3.event.dy;// tick(); // this is the key to make it work together with updating both px,py,x,y on d !// }//// function dragend(d, i) {// d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff// tick();// force.resume();// }//specify what to do when zoom event listener is triggeredfunction zoomed() {g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");}});</script>

总结

以上是生活随笔为你收集整理的D3js(三):force实例的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。