我使用问题d3js: Add quantitative dimension to Hierarchical Edge Bundling的答案来帮助我进行可视化处理,需要通过颜色区分强度。
但是,对于某些链接,该值未正确保存-对于某些节点,所有连接的链接共享相同的值,而不是在JSON文件中定义了正确的值。
从控制台:
{name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196 {name: "MMR_Politika územního rozvoje", imports: Array(52), size: 1, parent: {…}, key: "Politika územního rozvoje", …}depth: 2imports: (52) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]key: "Politika územního rozvoje"name: "MMR_Politika územního rozvoje"parent: {name: "MMR", children: Array(4), parent: {…}, key: "MMR", depth: 1, …}size: 1source: truetarget: truevalue: 8.333333333x: 10.434782608695652y: 290__proto__: Object
sep_scriptV3_sampleData.js:196
以此类推。...
来自JSON:
{"name": "MMR_Politika územního rozvoje", "imports": [{"link": "MMR_Strategie regionálního rozvoje", "value": 9.743589744}, {"link": "MS_Strategie pro rozvoj eJustice", "value": 8.333333333}, {"link": "MŽP_Plán odpadového hospodářství", "value": 2.956521739}, {"link": "MPSV_Strategie sociálního začleňování", "value": 2.481389578}, {"link": "MŠMT_Strategie vzdělávací politiky", "value": 2.222222222}, {"link": "MZ_Reforma psychiatrické péče", "value": 2.197802198}, {"link": "MPSV_Rozvoj sociálních služeb", "value": 2.051282051}, {"link": "ÚV_Boj proti sociálnímu vyloučení", "value": 1.683501684}, {"link": "MPSV_Koncepce sociálního bydlení", "value": 1.465201465}, {"link": "MŠMT_Strategie digitálního vzdělávání", "value": 1.360544218}, {"link": "MMR_Koncepce bydlení", "value": 1.333333333}, {"link": "MD_Dopravní politika", "value": 18.36734694}, {"link": "MPO_Akční plán energetické účinnosti", "value": 16.09195402}, {"link": "MD_Inteligentní dopravní systémy", "value": 15.97222222}, {"link": "MŽP_Environmentální bezpečnost", "value": 11.9047619},
.....显然,它为所有链接粘贴了一个值,而不是应有的唯一性。
完整的代码如下:
function sep_script() {
/*text = d3.select("body") //select the element on the page
.append("p") //append a new paragraph
.text("New paragraph sample!") //text for the paragraph
.attr("class", "title")
.style("color", "green")
.style("filter", "grayscale(.51)")
.style("filter", "opacity(0.3)"); //make a class for CSS */
/*
svgg = d3.select("body").append("svg") //selects page element and appends svg object
.attr("width", diameter/2) //size of the svg object
.attr("height", diameter/2) //-||-
.append("g") //makes a group selection
.attr("transform", "translate(" + radius*2 + "," + radius*2 + ")"); //centres the origin
*/
var diameter = 1060, //variables for the chart size
radius = diameter / 2,
innerRadius = radius - 240;
var curveBeta = 0.85 /*variable for the visual effect of bundling lines together
the higher the more concise, otherwise lines are all over the place*/
var splines = []; //for tension slider
var cluster = d3.layout.cluster() //creates a new cluster layout
.size([360, innerRadius])
.sort(null)
.value(function(d) { return d.size; });
var bundle = d3.layout.bundle();
var line = d3.svg.line.radial() //constructs a new radial line generator
.interpolate("bundle")
.tension(curveBeta) /* sets the curvature of the line
curveBundle is a type of curvature used for hiearchical data, the bigger the beta the more curved */
.radius(function(d) { return d.y; }) //sets how far the lines spread out from the origin for all the data
.angle(function(d) { return d.x / 180 * Math.PI; }); //positions the individual lines for individual data
var svg = d3.select("body").append("svg") //selects page element and appends svg object
.attr("width", diameter) //size of the svg object
.attr("height", diameter) //-||-
.append("g") //makes a group selection
.attr("transform", "translate(" + radius + "," + radius + ")"); //centres the origin
var link = svg.append("g").selectAll(".link"), //appends group and makes a selection of links
node = svg.append("g").selectAll(".node"); //appends group and makes a selection of nodes
//add the data and run function with innput (error, classes)
/* to convert strings into numbers:
d3.json("flare.json", type, function(error...)){...}
function type(d){
d.x = parseFloat(d.x);
d.y = parseFloat(d.y);
return d;
}
where x and y are column names (in a csv) */
d3.json("flare_new.json", function(error, classes) {
if (error) throw error;
var nodes = cluster.nodes(packageHierarchy(classes)), /* creates cluster layout from the "root" data
packageHierarchy - function declared later:
builds the hiearchy from all the data (children; keys are the names) */
links = packageImports(nodes)
splines = bundle(links); //added for tension slider
// added for color ---
var colorScale = d3.scale.quantize()
//.range(["#dcdc00", "#dcc000","#dca500","#dc8900","#dc6e00","#dc5200","#dc3700","#dc1b00","#dc0000"])
// .range(["#8bc3f6","#51acff","#2f86ff","#0051ff"])
.range(["black", "green", "red", "blue"])
//.range(["rgb(160, 160, 160)","rgb(140, 140, 140)","rgb(120, 120, 120)","rgb(100, 100, 100)","rgb(80, 80, 80)","rgb(60, 60, 60)","rgb(40, 40, 40)","rgb(20, 20, 20)","rgb(0, 0, 0)"])
.domain([0,100]);
// added for color ---
// added for opacity ---
var opacityScale = d3.scale.quantize()
.range([0])
//.range([0.02,0.02,0.015,0.015,0.015,0.005,0.005,0.005,0.005])
//.range([0.03,0.03,0.025,0.025,0.025,0.015,0.015,0.015,0.015])
//.range([0.04,0.04,0.035,0.035,0.035,0.025,0.025,0.025,0.025])
//.range([0.05,0.05,0.045,0.045,0.045,0.035,0.035,0.035,0.035])
.domain([0,100]);
// added for opacity --
link = link
.style("filter", "grayscale(1)")
.data(bundle(links))
.enter().append("path") //enter makes path for every data with following:
.each(function(d) { d.source = d[0], d.target = d[d.length - 1]; }) //returns all pairs of connected data
.attr("class", "link") //make a class for CSS
.attr("d", line) //d sets the "path" for the path and line sets the "looks"
// added for color and opacity---
.style("stroke", function(d){
return colorScale(d.target.value); //;
})
.style("stroke-opacity", function(d){
return opacityScale(d.target.value); //;
})
;
// added for color and opacity---
node = node
.data(nodes.filter(function(n) { return !n.parents;})) /*made visible parent names
original !n.children */
.enter().append("text")
.attr("class", "node")
.attr("dy", ".31em")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
.style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.text(function(d) { return d.key; })
.on("mouseover", mouseovered) //
.on("mouseout", mouseouted); //
//---------for tension slider
d3.select("input[type=range]").on("change", function() {
line.tension(this.value / 100);
link.attr("d", function(d, i) { return line(splines[i]); });
}); //---------for tension slider
});
//
function mouseovered(d) {
node
.each(function(n) { n.target = n.source = false; });
link
.classed("link--target", function(l) { if (l.target === d) return l.source.source = true; })
.classed("link--source", function(l) { if (l.source === d) return l.target.target = true; })
.filter(function(l) { return l.target === d || l.source === d; })
.each(function() { this.parentNode.appendChild(this); })
;
node
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; })
;
}
function mouseouted(d) {
link
.classed("link--target", false)
.classed("link--source", false);
node
.classed("node--target", false)
.classed("node--source", false);
}
//
// d3.select(self.frameElement).style("height", diameter + "px");
// Lazily construct the package hierarchy from class names.
function packageHierarchy(classes) {
var map = {};
function find(name, data) {
var node = map[name], i;
if (!node) {
node = map[name] = data || {name: name, children: []};
if (name.length) {
node.parent = find(name.substring(0, i = name.lastIndexOf("_")));
node.parent.children.push(node);
node.key = name.substring(i + 1);
}
}
return node;
}
classes.forEach(function(d) {
find(d.name, d);
});
return map[""];
}
// Return a list of imports for the given array of nodes.
function packageImports(nodes) {
var map = {},
imports = [];
// Compute a map from name to node.
nodes.forEach(function(d) {
map[d.name] = d;
});
// For each import, construct a link from the source to target node.
nodes.forEach(function(d) {
if (d.imports) d.imports.forEach(function(i) {
// added for color ---
var target = map[i.link];
target.value = i.value;
imports.push({source: map[d.name], target: target})
console.log(target); ///
// added for color --- old v4:
/* imports.push(map[d.data.name].path(map[i])); */
});
});
return imports;
}
// ----------------------------->>>>>> trying to set the filter
/*
var issue = svgg.selectAll(".issue")
.data(categories) // Select nested data and append to new svg group elements
.enter().append("g")
.attr("class", "issue");
var legendSpace = 450 / categories.length; // 450/number of issues (ex. 40)
issue.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("x", width + (margin.right/3) - 15)
.attr("y", function (d, i) { return (legendSpace)+i*(legendSpace) - 8; }) // spacing
.attr("fill",function(d) {
return d.visible ? color(d.name) : "#F1F1F2"; // If array key "visible" = true then color rect, if not then make it grey
})
.attr("class", "legend-box")
.on("click", function(d){ // On click make d.visible
d.visible = !d.visible; // If array key for this data selection is "visible" = true then make it false, if false then make it true
maxY = findMaxY(categories); // Find max Y rating value categories data with "visible"; true
yScale.domain([0,maxY]); // Redefine yAxis domain based on highest y value of categories data with "visible"; true
svg.select(".y.axis")
.transition()
.call(yAxis);
issue.select("path")
.transition()
.attr("d", function(d){
return d.visible ? line(d.values) : null; // If d.visible is true then draw line for this d selection
})
issue.select("rect")
.transition()
.attr("fill", function(d) {
return d.visible ? color(d.name) : "#F1F1F2";
});
})
.on("mouseover", function(d){
d3.select(this)
.transition()
.attr("fill", function(d) { return color(d.name); });
d3.select("#line-" + d.name.replace(" ", "").replace("/", ""))
.transition()
.style("stroke-width", 2.5);
})
.on("mouseout", function(d){
d3.select(this)
.transition()
.attr("fill", function(d) {
return d.visible ? color(d.name) : "#F1F1F2";});
d3.select("#line-" + d.name.replace(" ", "").replace("/", ""))
.transition()
.style("stroke-width", 1.5);
})
issue.append("text")
.attr("x", width + (margin.right/3))
.attr("y", function (d, i) { return (legendSpace)+i*(legendSpace); }) // (return (11.25/2 =) 5.625) + i * (5.625)
.text(function(d) { return d.name; });
*/
}