以下内容基于:http://bl.ocks.org/sjengle/5432087
我已经按照完整代码定义了节点标签。 但是当我使用鼠标悬停功能时:
function mouseovered(d) {
console.log("mouseOver");
//d3.select(this).style("font-weight", 700);
d3.select("#plot").selectAll(".nodeText")
.filter(function(l) { return l.target === d.name || l.source === d.name; })
.style("font-weight", 700);
}
过滤不起作用,并且在通过调试器运行时,l是未定义的。导致l不确定的原因是什么?
编辑。 l似乎没有属性l.target或l.source
完整代码如下:
function sep_script () {
var diameter = 1060;
var radius = diameter / 2;
var margin = 240;
// Generates a tooltip for a SVG circle element based on its ID
function addTooltip(circle) {
var x = parseFloat(circle.attr("cx"));
var y = parseFloat(circle.attr("cy"));
var r = parseFloat(circle.attr("r"));
var text = circle.attr("id");
var tooltip = d3.select("#plot")
.append("text")
.text(text)
.attr("x", x)
.attr("y", y)
.attr("dy", -r * 2)
.attr("id", "tooltip");
var offset = tooltip.node().getBBox().width / 2;
if ((x - offset) < -radius) {
tooltip.attr("text-anchor", "start");
tooltip.attr("dx", -r);
}
else if ((x + offset) > (radius)) {
tooltip.attr("text-anchor", "end");
tooltip.attr("dx", r);
}
else {
tooltip.attr("text-anchor", "middle");
tooltip.attr("dx", 0);
}
}
// Draws an arc diagram for the provided undirected graph
function drawGraph(graph) {
// create svg image
var svg = d3.select("body").select("#circle")
.append("svg")
.attr("width", diameter)
.attr("height", diameter);
// draw border around svg image
// svg.append("rect")
// .attr("class", "outline")
// .attr("width", diameter)
// .attr("height", diameter);
// create plot area within svg image
var plot = svg.append("g")
.attr("id", "plot")
.attr("transform", "translate(" + radius + ", " + radius + ")");
// draw border around plot area
// plot.append("circle")
// .attr("class", "outline")
// .attr("r", radius - margin);
// fix graph links to map to objects instead of indices
graph.links.forEach(function(d, i) {
d.source = isNaN(d.source) ? d.source : graph.nodes[d.source];
d.target = isNaN(d.target) ? d.target : graph.nodes[d.target];
});
// calculate node positions
circleLayout(graph.nodes);
// draw edges first
//drawLinks(graph.links);
// draw Curves
//drawCurves(graph.links);
// NEW draw bundled Curves (Not bundled as I wish)
drawBundledButNotCurves(graph.links);
// NEW draw bundled Curves
//drawBundledCurves(graph.links);
// draw nodes last
drawNodes(graph.nodes);
}
// Calculates node locations
function circleLayout(nodes) {
// sort nodes by group
nodes.sort(function(a, b) {
return a.group - b.group;
});
// use to scale node index to theta value
var scale = d3.scale.linear()
.domain([nodes.length, 0])
.range([Math.PI, 3 * Math.PI]);
// calculate theta for each node
nodes.forEach(function(d, i) {
// calculate polar coordinates
var theta = scale(i);
var radial = radius - margin;
// convert to cartesian coordinates
d.x = radial * Math.sin(theta);
d.y = radial * Math.cos(theta);
});
}
// Draws nodes with tooltips
function drawNodes(nodes) {
// OLD used to assign nodes color by group
//var color = d3.scale.category20();
// NEW colors for nodes with white ones to make categories look bundled
//var colors = ['steelblue', '#ffffff00'];
// colors for nodes to hide circles
var colors = ['#ffffff00'];
var color = d3.scale.ordinal().range(colors);
d3.select("#plot").selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("id", function(d, i) { return d.name; })
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return d.y; })
.attr("r", 5)
.style("fill", function(d, i) { return color(d.group); })
.on("mouseover", function(d, i) { addTooltip(d3.select(this)); })
.on("mouseout", function(d, i) { d3.select("#tooltip").remove(); });
// NEW scale for rotation
var rotationScale = d3.scale.pow()
.exponent(1.9)
.range([-90, 90])
.domain([-290,290]);
// NEW define
// NEW add text labels
d3.select("#plot").selectAll(".nodeText") //???? ".nodeText"
.data(nodes)
.enter()
.append("text")
.attr("class", "nodeText")
.attr("dy", ".31em")
.attr("transform", function(d) { return "translate(" + (d.x) + ", " + (d.y) + ")rotate(" + (d.x < 0 ? rotationScale(-d.y) : rotationScale(d.y)) + ")translate(" + (d.x < 0 ? (-8) : (8)) + ", " + 0 + ")"})
// sets the origin of rotation to the node's location ^^^^^^^^^^ ^^rotates the label for right half the other way round then the left half ^^and shifts the label a bit from the circle
.style("text-anchor", function(d) { return d.x > 0 ? "start" : "end"; })
//.style("text_anchor", "bottom")
.text(function(d) { return d.name; })
//.on("mouseover", mouseovered)
//.on("mouseout", mouseouted);
.on("mouseover", mouseovered)
.on("mouseout", mouseouted);
}
// NEW Functions for mouseovered and mouseouted
// https://gist.github.com/hughlomas/1678703 - simple mouseover functions
function mouseovered(d) {
console.log("mouseOver");
//d3.select(this).style("font-weight", 700);
d3.select("#plot").selectAll(".nodeText")
.filter(function(l) { return l.name === d.name || l.name === d.name; })
//.filter(function(l) { return console.log(l)})
.style("font-weight", 700);
}
function mouseouted(d) {
console.log("mouseOut");
d3.select(this).style("font-weight", 400);
d3.select("#plot").selectAll("text").style("font-weight", 400);
}
// NEW added for color ---
var colorScale = d3.scale.quantize() .range(["#ffffff00","#8bc3f6","#8bc3f6","#8bc3f6","#51acff","#51acff","#51acff","#2f86ff","#2f86ff","#2f86ff","#0051ff","#0051ff","#0051ff"])
.domain([-0.06666666666666,0.8]);
// added for color ---
// NEW Draws bundled curved edges between nodes (Not bundled as I wish)
function drawBundledButNotCurves(links) {
// https://stackoverflow.com/questions/34263110/d3-js-edge-bundling-without-hierachy
d3.select("#plot").selectAll(".link")
.data(links)
.enter()
.append("path")
.attr("class", "link")
.attr("d", function(d){
var lineData = [
{
x: Math.round(d.target.x),
y: Math.round(d.target.y)
}, {
x: Math.round(d.target.x) - Math.round(d.target.x)/3,
y: Math.round(d.target.y) - Math.round(d.target.y)/3
},
{
x: Math.round(d.source.x) - Math.round(d.source.x)/3,
y: Math.round(d.source.y) - Math.round(d.source.y)/3
},{
x: Math.round(d.source.x),
y: Math.round(d.source.y)
}];
return `M${lineData[0].x},${lineData[0].y}C${lineData[1].x},${lineData[1].y},${lineData[2].x},${lineData[2].y},${lineData[3].x},${lineData[3].y} `;
})
// added for color
.style("stroke", function(d){
return colorScale(d.value)
});
}
d3.json("flare_newC.json", drawGraph);
}
以下是数据:
{"nodes": [{"name": "OP PIK_01.1 Rozvoj výzkumu a vývoje pro inovace", "group": 1}, {"name": "OP PIK_01.2 Rozvoj podnikání a konkurenceschopnosti malých a středních podniků", "group": 1}, {"name": "OP PIK_01.3 Účinné nakládání energií, rozvoj energetické infrastruktury a obnovitelných zdrojů energie, podpora zavádění nových technologií v oblasti nakládání energií a druhotných surovin", "group": 1}, {"name": "OP PIK_01.4 Rozvoj vysokorychlostních přístupových sítí k internetu a informačních a komunikačních technologií", "group": 1}, {"name": "OP PIK_01.5 Technická pomoc", "group": 1}, ...
, {"name": "", "group": 2}, {"name": "", "group": 4}, {"name": "", "group": 6}, {"name": "", "group": 8}, {"name": "", "group": 10}, {"name": "", "group": 12}, {"name": "", "group": 14}, {"name": "", "group": 16}
], "links": [{"value": 0.13757455268389662, "target": 1, "source": 0}, {"value": 0.07236842105263158, "target": 2, "source": 0}, {"value": 0.03948896631823461, "target": 3, "source": 0}, {"value": 0.0, "target": 4, "source": 0}, {"value": 0.007836990595611285, "target": 5, "source": 0}, {"value": 0.009244992295839754, "target": 6, "source": 0}, {"value": 0.0005341167044999333, "target": 7, "source": 0}, {"value": 0.0, "target": 8, "source": 0}, {"value": 0.06844336765596608, "target": 9, "source": 0}, {"value": 0.0, "target": 10, "source": 0}, {"value": 0.0014781966001478197, "target": 11, "source": 0}, {"value": 0.0, "target": 12, "source": 0}, {"value": 0.0, "target": 13, "source": 0}, {"value": 0.0, "target": 14, "source": 0}, {"value": 0.0, "target": 15, "source": 0}, {"value": 0.0, "target": 16, "source": 0}, {"value": 0.0, "target": 17, "source": 0}, {"value": 0.0, "target": 18, "source": 0}, {"value": 0.004398826979472141, "target": 19, "source": 0}, {"value": 0.0018248175182481751, "target": 20, "source": 0}, {"value": 0.0, "target": 21, "source": 0}, {"value": 0.0022197558268590455, "target": 22, "source": 0}, {"value": 0.0, "target": 23, "source": 0}, ... ]}