javascript - 箭头指向源节点的 D3 网络图

标签 javascript d3.js

这里我正在使用 D3 网络图表,在我的 fiddle 中,您可以看到箭头指向目标节点(右侧),请参见下面的屏幕截图: enter image description here

但我需要的是相反的,如下所示: enter image description here

有人知道我怎样才能做到这一点吗?

这是我的代码:

var width = 500
height = 550;

var cluster = d3.layout.cluster()
.size([height - height * 0, width - width * 0.5]);

var diagonal = d3.svg.diagonal()
.projection(function(d) {
    return [d.y, d.x];
});

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "padding-left:5%")
.attr("pointer-events", "all")
.call(d3.behavior.zoom().on("zoom", redraw));

 // Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);

var vis = svg
.append("svg:g");

vis.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr("fill", 'white');

function redraw() {
   vis.attr("transform",
     "translate(" + d3.event.translate + ")" +
     " scale(" + d3.event.scale + ")");
 }

 var root = {
  "name": "output",
  "children": [{
    "name": "sum",
    "children": [{
        "name": "Base",
        "children": [],
        "weight": 1.0000002576768052
    }, {
        "name": "H0",
        "children": [],
        "weight": 2.5767680512326025e-7
    }]
  }]
};

var nodes = cluster.nodes(root),
 links = cluster.links(nodes);

vis.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");

var link = vis.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("marker-end", "url(#end)")
.attr("d", diagonal);


var node = vis.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
    return "translate(" + d.y + "," + d.x + ")";
})
.on("mouseover", mouseover)
.on("mouseout", mouseout);

node.append("circle")
.attr("r", 4.5)
.style("fill", "#3182bd");

node.append("svg:text")
 .attr("dx", function(d) {
    return d.children ? -8 : 8;
})
 .attr("dy", 3)
 .style("text-anchor", function(d) {
    return d.children ? "end" : "start";
 })
 .style("fill", "#3182bd")
 .text(function(d) {
    return d.name;
 });

function mouseover() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 9)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("stroke-width", ".5px")
    .style("font", "22.8px serif")
    .style("opacity", 1);
}

function mouseout() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 4.5)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("font", "12px serif")
    .style("opacity", 0.8);
}

d3.select(self.frameElement).style("height", height + "px");

最佳答案

只需两个简单的步骤即可实现此目的

  • 将标记放在路径的另一端.attr("marker-start", "url(#end)")
  • 将标记旋转 180 度 .attr("orient", 180)

但是 MDN 上没有足够的关于标记属性的信息 this page已经足够了:)

var width = 500
height = 550;

var cluster = d3.layout.cluster()
  .size([height - height * 0, width - width * 0.5]);

var diagonal = d3.svg.diagonal()
  .projection(function(d) {
    return [d.y, d.x];
  });

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .attr("style", "padding-left:5%")
  .attr("pointer-events", "all")
  .call(d3.behavior.zoom().on("zoom", redraw));

// Define the div for the tooltip
var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

var vis = svg
  .append("svg:g");

vis.append("svg:rect")
  .attr("width", width)
  .attr("height", height)
  .attr("fill", 'white');



function redraw() {
  vis.attr("transform",
    "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}

//var root = {"name":"Canada","children":[{"name":"Newfoundland","children":[{"name":"St. John's"}]},{"name":"PEI","children":[{"name":"Charlottetown"}]},{"name":"Nova Scotia","children":[{"name":"Halifax"}]},{"name":"New Brunswick","children":[{"name":"Fredericton"}]},{"name":"Quebec","children":[{"name":"Montreal"},{"name":"Quebec City"}]},{"name":"Ontario","children":[{"name":"Toronto"},{"name":"Ottawa"}]},{"name":"Manitoba","children":[{"name":"Winnipeg"}]},{"name":"Saskatchewan","children":[{"name":"Regina"}]},{"name":"Nunavuet","children":[{"name":"Iqaluit"}]},{"name":"NWT","children":[{"name":"Yellowknife"}]},{"name":"Alberta","children":[{"name":"Edmonton"}]},{"name":"British Columbia","children":[{"name":"Victoria"},{"name":"Vancouver"}]},{"name":"Yukon","children":[{"name":"Whitehorse"}]}]} ; 
var root = {
  "name": "output",
  "children": [{
    "name": "sum",
    "children": [{
      "name": "Base",
      "children": [],
      "weight": 1.0000002576768052
    }, {
      "name": "H0",
      "children": [],
      "weight": 2.5767680512326025e-7
    }]
  }]
};

var nodes = cluster.nodes(root),
  links = cluster.links(nodes);

vis.append("svg:defs").selectAll("marker")
  .data(["end"]) // Different link/path types can be defined here
  .enter().append("svg:marker") // This section adds in the arrows
  .attr("id", String)
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", 0)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", 180)
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

var link = vis.selectAll(".link")
  .data(links)
  .enter().append("path")
  .attr("class", "link")
  .attr("marker-start", "url(#end)")
  .attr("d", diagonal);
/*.on("mouseover", function(d) {
	//console.log(d.children.weight);	
	        div.transition()		
                .duration(200)		
                .style("opacity", .9);		
            div	.html(d.y)	
                .style("left", (d3.event.pageX) + "px")		
                .style("top", (d3.event.pageY - 28) + "px");	
            })					
        .on("mouseout", function(d) {		
            div.transition()		
                .duration(500)		
                .style("opacity", 0);	
        });*/


var node = vis.selectAll(".node")
  .data(nodes)
  .enter().append("g")
  .attr("class", "node")
  .attr("transform", function(d) {
    return "translate(" + d.y + "," + d.x + ")";
  })
  .on("mouseover", mouseover)
  .on("mouseout", mouseout);

node.append("circle")
  .attr("r", 4.5)
  .style("fill", "#3182bd");

node.append("svg:text")
  .attr("dx", function(d) {
    return d.children ? -8 : 8;
  })
  .attr("dy", 3)
  .style("text-anchor", function(d) {
    return d.children ? "end" : "start";
  })
  .style("fill", "#3182bd")
  .text(function(d) {
    return d.name;
  });


/*var linktext = vis.append("svg:g").selectAll("g.linklabelholder").data(links);
	
    linktext.enter().append("g").attr("class", "linklabelholder")
     .append("text")
     .attr("class", "linklabel")
	 .style("font-size", "13px")
     .attr("x", "50")
	 .attr("y", "-20")
     .attr("text-anchor", "start")
	   .style("fill","#000")
	 .append("textPath")
    .attr("xlink:href",function(d,i) { return "#linkId_" + i;})
     .text(function(d) { 
	 return d.type; 
	 });*/

function mouseover() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 9)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("stroke-width", ".5px")
    .style("font", "22.8px serif")
    .style("opacity", 1);
}

function mouseout() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 4.5)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("font", "12px serif")
    .style("opacity", 0.8);
}

d3.select(self.frameElement).style("height", height + "px");
.link {
  fill: none;
  stroke: #ccc;
  opacity: 0.4;
  stroke-width: 1.5px;
}
.node circle {
  stroke: #fff;
  opacity: 0.8;
  stroke-width: 1.5px;
}
.node:not(:hover) .nodetext {
  display: none;
}
text {
  font: 12px serif;
  opacity: 0.8;
  pointer-events: none;
}
div.tooltip {
  position: absolute;
  text-align: center;
  width: 60px;
  height: 28px;
  color: black;
  padding: 2px;
  font: 12px sans-serif;
  background: lightsteelblue;
  border: 0px;
  border-radius: 8px;
  pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

关于javascript - 箭头指向源节点的 D3 网络图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37130075/

相关文章:

javascript - 正则表达式 JavaScript 文本文件

javascript - JQuery 模板 - 使用字符串作为数据

javascript - 沿最佳圆周分布 n 组圆

javascript - D3 一次为一个路径系列制作动画

d3.js - 为什么第一个链接项被跳过?

javascript - 使用WMODE =“window”时,使用JS在Flash插件上捕获右键单击事件

javascript - Jquery 后期绑定(bind)使用 on - 旧表单不起作用?

javascript - 对象原型(prototype) toString 调用 - JavaScript

javascript - 使用 d3.js 创建词云

javascript - d3js v5 + topojson v3 后台访问对象的属性