【发布时间】:2025-12-19 03:25:06
【问题描述】:
var data =
[{"seq":"1","start":"Account","end":"Order","relation":"Account","rows":"1"},
{"seq":"2","start":"Account","end":"Attachment","relation":"Parent","rows":"10"}
,{"seq":"3","start":"Order","end":"Account","relation":"Account","rows":"15"}
,{"seq":"4","start":"Attachment","end":"Account","relation":"Parent","rows":"55"}
,{"seq":"5","start":"Attachment","end":"Campaign","relation":"Parent","rows":"45"}
,{"seq":"6","start":"Attachment","end":"Lead","relation":"Parent","rows":"47"}
,{"seq":"7","start":"Lead","end":"Attachment","relation":"Parent","rows":"75"}
,{"seq":"8","start":"Campaign","end":"Attachment","relation":"Parent","rows":"34"},
{"seq":"9","start":"Order","end":"Account","relation":"Account","rows":"99"}
,{"seq":"10","start":"Attachment","end":"Account","relation":"Parent","rows":"12"}
,{"seq":"11","start":"Attachment","end":"Campaign","relation":"Parent","rows":"5"}
,{"seq":"12","start":"Attachment","end":"Lead","relation":"Parent","rows":"75"}];
var ellipseSelected, pathSelected, parentNodeX, parentNodeY, relationshipName, indexEdge, fromData, toData, nodeSelected, startNodeSelected;
//flag =1 ,when we have both src and trg
var flag = 1;
var newCount = 0;
var edges = d3.selectAll('.edge');
var path = d3.selectAll('.path')
var allEllipse = d3.selectAll('ellipse');
var allNodes = d3.selectAll('.node');
var theGraph = document.getElementById('graph0') //getContainer
var polygon = document.getElementsByTagName('polygon')[0] //getPolygon to insert after
var allEdgesJS = document.getElementsByClassName("edge"); //select all Edges
for (var i = 0; i < allEdgesJS.length; i++) { //Loop through edges to move
theGraph.insertBefore(allEdgesJS[i], polygon.nextSibling); //insert after polygon
}
function ellipseAdd() {
d3.select(ellipseSelected.parentNode)
.append("circle")
.attr('cx', parentNodeX) //thisParentBBox.left + thisParentBBox.width/2)
.attr('cy', parentNodeY)
.attr("r", 10)
.attr("stroke-width", 1)
.attr("stroke", "white")
.style('fill', '#CE2029');
d3.select(ellipseSelected.parentNode)
.data([toData])
.append("text")
.attr('x', parentNodeX - 8)
.attr('y', parentNodeY + 4).text(0).style('fill', 'white')
.attr("font-size", "8px")
.transition()
.duration(3000)
.tween("text", function(d) {
var i = d3.interpolate(fromData, d),
prec = (d + "").split("."),
round = (prec.length > 1) ? Math.pow(10, prec[1].length) : 1;
return function(t) {
this.textContent = Math.round(i(t) * round) / round;
};
});
}
function blinker() {
if (flag == 0) {
//for adding ellipse and text to it
ellipseAdd();
} else {
//blink 3 things\
//ellipse
ellipseAdd();
d3.select('#' + indexAndEdge[indexEdge].id + ' path').style('opacity', 1)
.transition().style('stroke', 'grey').duration(300).style('opacity', 1)
.transition().style('stroke', '#CE2029').style('stroke-width', 1)
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('stroke', 'grey').duration(300).style('opacity', 1)
.transition().style('stroke', '#CE2029').style('stroke-width', 1)
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('stroke', 'grey').duration(300).style('opacity', 1)
.transition().style('stroke', '#CE2029').style('stroke-width', 1)
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('stroke', 'grey').style('stroke-width', 1).duration(300).style('opacity', 1)
.transition().style('stroke', "#ff800e").style('stroke-width', 1); //select current id from array //select current id from array
d3.select('#' + indexAndEdge[indexEdge].id + ' polygon')
.transition().style('stroke', 'grey').style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('fill', '#CE2029').style('stroke', '#CE2029').style('stroke-width', 2)
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('stroke', 'grey').style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('fill', '#CE2029').style('stroke', '#CE2029').style('stroke-width', 2)
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('stroke', 'grey').style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('stroke', '#CE2029').style('fill', '#CE2029').style('stroke-width', 2)
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('stroke', 'grey').style('fill', 'grey').style('stroke-width', 1).duration(300).style('opacity', 1)
.transition().style('stroke', "#ff800e").style('fill', "#ff800e").style('stroke-width', 1); //select current id from array
d3.select('#' + indexAndEdge[indexEdge].id + ' text').style('opacity', 0)
.transition().style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('fill', '#CE2029')
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('fill', '#CE2029')
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('fill', '#CE2029').style('fill', '#CE2029')
.transition().duration(300).duration(300).style('opacity', 1)
.transition().style('fill', 'grey').duration(300).style('opacity', 1)
.transition().style('fill', "#ff800e");
}
}
edges.style('opacity', 1);
allNodes.style('fill', "white");
path.style('fill', "yellow");
var indexAndEdge = [];
var countOnNode = [];
edges.each(function(d, i) {
var thisEdgeCount = this.id.substring(4);
debugger
indexAndEdge.push({ //push index you are at, the edge count worked out above and the id
index: i,
count: thisEdgeCount,
id: this.id,
start: String(this.childNodes[0].childNodes[0].nodeValue).split("->")[0],
destination: String(this.childNodes[0].childNodes[0].nodeValue).split("->")[1],
relation: this.childNodes[6].childNodes[0]
})
d3.select('#' + indexAndEdge[i].id + ' polygon').style('fill', 'grey').style('stroke', 'grey');
d3.select('#' + indexAndEdge[i].id + ' path').style('stroke', 'grey');
});
d3.selectAll('.node').each(function(d, i) {
var thisNodeCount = this.id;
debugger
countOnNode.push({ //push index you are at, the edge count worked out above and the id
id: thisNodeCount,
prevData: 0,
incrementData: 0,
title: this.childNodes[0].childNodes[0].nodeValue,
name: String(this.childNodes[4].childNodes[0].nodeValue)
})
});
function timer() {
setTimeout(function(d) {
if (newCount < data.length) { //if we havent gone through all edges
if (data[newCount].end.length == 0) {
flag = 0;
for (j = 0; j < allNodes[0].length; j++) {
//if sourseName matches
if (String(allNodes[0][j].childNodes[4].childNodes[0].nodeValue) == data[newCount].start) {
ellipseSelected = d3.selectAll('.node')[0][j].childNodes[2];
parentNodeX = ellipseSelected.attributes.cx.value - ellipseSelected.attributes.rx.value + (2 * ellipseSelected.attributes.rx.value);
parentNodeY = ellipseSelected.attributes.cy.value - (ellipseSelected.attributes.ry.value / 2);
//send the data to interpolate
//match id and update prevData ,incrementData
for (var l = 0; l < countOnNode.length; l++) {
if (countOnNode[l].id == d3.selectAll('.node')[0][j].id) {
countOnNode[l].prevData = countOnNode[l].incrementData;
countOnNode[l].incrementData = data[newCount].rows;
fromData = countOnNode[l].prevData;
toData = countOnNode[l].incrementData;
}
}
blinker();
flag = 1;
if (flag == 1) {
break;
}
}
}
} else {
//check relation and targetNode
//check target
flag = 1;
for (var j = 0; j < allNodes[0].length; j++) {
if (String(allNodes[0][j].childNodes[4].childNodes[0].nodeValue) == data[newCount].end) {
ellipseSelected = d3.selectAll('.node')[0][j].childNodes[2];
parentNodeX = ellipseSelected.attributes.cx.value - ellipseSelected.attributes.rx.value + (2 * ellipseSelected.attributes.rx.value);
parentNodeY = ellipseSelected.attributes.cy.value - (ellipseSelected.attributes.ry.value / 2);
for (var l = 0; l < countOnNode.length; l++) {
if (countOnNode[l].id == d3.selectAll('.node')[0][j].id) {
countOnNode[l].prevData = countOnNode[l].incrementData;
countOnNode[l].incrementData = +data[newCount].rows + +countOnNode[l].prevData;
fromData = countOnNode[l].prevData;
toData = countOnNode[l].incrementData;
nodeSelected = l;
// console.log(" j =" + j + "l "+l+ " fromData " + fromData + " toData "+toData);
}
}
debugger
for (var ll = 0; ll < countOnNode.length; ll++) {
if (countOnNode[ll].name == data[newCount].start) {
debugger;
// console.log(data[newCount]);
startNodeSelected = ll;
}
}
debugger
//set the edge by checking relation
for (var k = 0; k < indexAndEdge.length; k++) {
//if(edges[0][k].childNodes[7].childNodes[0] == indexAndEdge)
if ((data[newCount].relation.trim() == (String(indexAndEdge[k].relation.nodeValue).trim()) &&
(((countOnNode[nodeSelected].title == indexAndEdge[k].destination) && (countOnNode[startNodeSelected].title == indexAndEdge[k].start)) || ((countOnNode[nodeSelected].title == indexAndEdge[k].start) && (countOnNode[startNodeSelected].title == indexAndEdge[k].destination))))) {
indexEdge = k;
}
}
blinker();
flag = 0;
if (flag == 0) {
break;
}
}
}
}
//allEllipse
newCount++;
timer();
} else {
// count =0 ;
timer()
console.log('end') //end
}
}, 3000)
}
timer();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: graphname Pages: 1 -->
<svg width="308pt" height="131pt"
viewBox="0.00 0.00 308.09 131.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 127)">
<title>graphname</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-127 304.095,-127 304.095,4 -4,4"/>
<!-- 0 -->
<g id="node1" class="node"><title>0</title>
<ellipse fill="#b2dfee" stroke="#b2dfee" cx="51.4971" cy="-105" rx="42.4939" ry="18"/>
<text text-anchor="middle" x="51.4971" y="-101.3" font-family="Times New Roman,serif" font-size="14.00">Account</text>
</g>
<!-- 1 -->
<g id="node2" class="node"><title>1</title>
<ellipse fill="#b2dfee" stroke="#b2dfee" cx="177.497" cy="-18" rx="51.9908" ry="18"/>
<text text-anchor="middle" x="177.497" y="-14.3" font-family="Times New Roman,serif" font-size="14.00">Attachment</text>
</g>
<!-- 0->1 -->
<g id="edge1" class="edge"><title>0->1</title>
<path fill="none" stroke="#cd0000" d="M81.6636,-83.6496C104.156,-68.4764 134.397,-48.0758 154.846,-34.2806"/>
<polygon fill="#cd0000" stroke="#cd0000" points="79.4899,-80.894 73.1573,-89.388 83.4047,-86.697 79.4899,-80.894"/>
<text text-anchor="middle" x="143.997" y="-57.8" font-family="Times New Roman,serif" font-size="14.00"> Parent </text>
</g>
<!-- 2 -->
<g id="node3" class="node"><title>2</title>
<ellipse fill="#b2dfee" stroke="#b2dfee" cx="32.4971" cy="-18" rx="32.4942" ry="18"/>
<text text-anchor="middle" x="32.4971" y="-14.3" font-family="Times New Roman,serif" font-size="14.00">Order</text>
</g>
<!-- 0->2 -->
<g id="edge2" class="edge"><title>0->2</title>
<path fill="none" stroke="#cd0000" d="M36.6269,-78.2339C35.365,-75.1966 34.2755,-72.0805 33.4971,-69 30.8171,-58.3937 30.5329,-46.1155 30.9355,-36.3806"/>
<polygon fill="#cd0000" stroke="#cd0000" points="33.6008,-80.0185 41.0756,-87.527 39.9146,-76.9959 33.6008,-80.0185"/>
<text text-anchor="middle" x="61.4971" y="-57.8" font-family="Times New Roman,serif" font-size="14.00"> Account </text>
</g>
<!-- 3 -->
<g id="node4" class="node"><title>3</title>
<ellipse fill="#b2dfee" stroke="#b2dfee" cx="177.497" cy="-105" rx="47.3916" ry="18"/>
<text text-anchor="middle" x="177.497" y="-101.3" font-family="Times New Roman,serif" font-size="14.00">Campaign</text>
</g>
<!-- 3->1 -->
<g id="edge3" class="edge"><title>3->1</title>
<path fill="none" stroke="#cd0000" d="M177.497,-76.7339C177.497,-63.4194 177.497,-47.806 177.497,-36.1754"/>
<polygon fill="#cd0000" stroke="#cd0000" points="173.997,-76.7989 177.497,-86.799 180.997,-76.799 173.997,-76.7989"/>
<text text-anchor="middle" x="198.997" y="-57.8" font-family="Times New Roman,serif" font-size="14.00"> Parent </text>
</g>
<!-- 4 -->
<g id="node5" class="node"><title>4</title>
<ellipse fill="#b2dfee" stroke="#b2dfee" cx="271.497" cy="-105" rx="28.6953" ry="18"/>
<text text-anchor="middle" x="271.497" y="-101.3" font-family="Times New Roman,serif" font-size="14.00">Lead</text>
</g>
<!-- 4->1 -->
<g id="edge4" class="edge"><title>4->1</title>
<path fill="none" stroke="#cd0000" d="M251.874,-81.4584C243.735,-72.5603 233.988,-62.4628 224.497,-54 216.904,-47.2291 208.071,-40.4074 200.126,-34.6078"/>
<polygon fill="#cd0000" stroke="#cd0000" points="249.277,-83.8042 258.567,-88.8979 254.481,-79.1226 249.277,-83.8042"/>
<text text-anchor="middle" x="259.997" y="-57.8" font-family="Times New Roman,serif" font-size="14.00"> Parent </text>
</g>
</g>
</svg>
在这里,圆圈被添加到 .svg 文件中。然后向该圆圈添加文本。我想在圆心添加文字,如果数字更大,比如 10000 ,它应该适合那个圆。
我试过了 .attr('高度', '汽车') .attr('文本锚', '中间')
但是,由于文本的位置取决于添加的节点(存在于 .svg 文件中)而不是圆形位置,因此它不起作用。
【问题讨论】:
标签: javascript d3.js svg