我能够在应用程序的初始加载时使用json数据绘制树结构。
现在我的要求是,点击按钮我应该能够为每个工作正常的节点添加更多的text / css。 我实际上使用的是最初用于绘制树的相同功能,能够在按钮触发器上交换数据。
当我这样做时,单击第一级节点(扩展到第二级),第一级路径从g标签中消失,所选节点更改位置并位于第二级数据中。
厌倦了所有可能的方式,任何人都可以帮助解决这个问题。
提前致谢
以下是使用的树函数
//To draw tree structure for the selected data
drawTree: function() {
var driverTree = this;
var id = "#" + this.getView().byId("chartArea").sId;
// ************** Generate the tree diagram *****************
var treeData = driverTree.treeModel.oData;
var radius = 40;
var width = $(id).width();
var height = window.innerHeight;
var maxLabel = 1500;
var i = 0,
duration = 450,
root;
var tree = d3.layout.tree()
.size([height, width])
.separation(function(a, b) {
return (a.parent == b.parent ? 1 : 2);
});
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
}
var slider = d3.scale.linear()
.domain([1, 100])
.range([1, 100])
.clamp(true);
var canvasWidth = radius * 2 + margin.left + margin.right,
canvasHeight = radius * 2 + margin.top + margin.bottom;
var color = d3.scale.category10();
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
});
var pie = d3.layout.pie()
.value(function(d) {
if (isNaN(parseFloat(d.value)))
return 0;
else
return parseFloat(d.value);
})
.sort(null);
// arc object
var arc = d3.svg.arc()
.outerRadius(40)
.innerRadius(20);
//var id = "#" + chartArea.sId;
d3.select(id).select("svg").remove();
driverTree.zoomListener = d3.behavior.zoom()
.scaleExtent([0.1, 3])
.on("zoom", function(d) {
zoomed(d);
});
var svgGroup = d3.select(id).append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "tooltip")
.call(driverTree.zoomListener);
function zoomed(d) {
if (driverTree.hoizMode)
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")rotate(90,50,50)");
else
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
var svg = svgGroup.append("g")
.attr("transform", "translate(" + width + "," + (height / 2) / 2 + ") rotate(90,50,50)");
root = treeData;
root.x0 = height / 2;
root.y0 = 0;
var div = d3.select("body").append("div").attr("class", "tooltip").style("opacity", "0");
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
root.children.forEach(collapse);
//update(root);
//d3.select(self.frameElement).style("height", "800px");
var circumference_r = 35;
function update(source) {
var levelWidth = [1];
var childCount = function(level, n) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) levelWidth.push(0);
levelWidth[level + 1] += n.children.length;
n.children.forEach(function(d) {
childCount(level + 1, d);
});
}
};
childCount(0, root);
var newHeight = d3.max(levelWidth) * 263.6; // 25 pixels per line
tree = tree.size([newHeight, window.innerHeight]);
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) {
d.y = d.depth * 180;
});
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("id", function(d) {
return "id" + d.title;
})
.attr("class", "node")
.attr("transform", function(d) {
if (driverTree.hoizMode)
return "translate(" + source.y0 + "," + source.x0 + ") rotate(-90)";
else
return "translate(" + source.y0 + "," + source.x0 + ") rotate(0)";
})
.on("mouseover", function(d) {
mouseover(d);
})
.on("mousemove", function(d) {
mousemove(d);
})
.on("mouseout", function(d) {
mouseout(d);
});
if (driverTree.editTree) {
nodeEnter.append("rect")
.attr("id", "hideButton")
.attr("width", function(d) {
if (d.id != "NODE1") return "40px";
})
.attr("transform", function(d) {
if (d.id != "NODE1") return "translate(-40,-70)";
})
.attr("rx", "5")
.attr("ry", "5")
.attr("height", function(d) {
if (d.id != "NODE1") return "25px";
})
.style("stroke", "#999faa")
.style("stroke-width", "2px")
.style("fill", function(d) {
if (d.isHidden) return "#000f2b";
else return "#8E94A1";
})
.on("click", function(d) {
d.isHidden = !d.isHidden;
if (d.isHidden) return this.style.fill = "#000f2b";
else return this.style.fill = "#8E94A1";
});
nodeEnter.append("text")
.attr("id", "hideText")
.attr("transform", "translate(-31,-54)")
.style("fill", "#eee")
.text(function(d) {
if (d.id != "NODE1") return "Hide";
})
.on("click", function(d) {
d.isHidden = !d.isHidden;
if (d.isHidden) return d3.select(this.parentNode).select("rect").style("fill", "#000f2b");
else return d3.select(this.parentNode).select("rect").style("fill", "#8E94A1");
});
}
nodeEnter.append("circle")
.attr("r", "40")
.on("click", click);
nodeEnter.append("text")
.attr("id", function(d) {
return "ct" + d.title;
})
.attr("x", "-8")
.attr("y", "4")
.text(function(d) {
return brevoVDT.util.Formatter.amountToMillions(d.value);
})
.on("click", click);
nodeEnter.append("text")
.attr("transform", "translate(55,-10)")
.text(function(d) {
return "Org Value - " + brevoVDT.util.Formatter.amountToMillions(d.value_org);
})
nodeEnter.append("text")
.attr("id", function(d) {
return "cv" + d.title;
})
.attr("transform", "translate(55,5)")
.text(function(d) {
return "Currenet Value - " + brevoVDT.util.Formatter.amountToMillions(d.value);
})
nodeEnter.append("text")
.attr("id", function(d) {
return "dv" + d.title;
})
.attr("transform", "translate(55,20)")
.text(function(d) {
return "Difference " + brevoVDT.util.Formatter.amountToMillions(parseFloat(d.value_org) - parseFloat(d.value));
})
.style("fill", function(d) {
var value = parseFloat(d.value_org) - parseFloat(d.value);
if (value > 0) return "green";
else if (value < 0) return "red";
else return "black";
})
/*nodeEnter.append("text")
.attr("transform", "translate(-50,58)")
.attr("text-anchor", "start")
.text(function(d) {
return d.title;
})*/
nodeEnter.append("rect")
.attr("width", "130px")
.attr("transform", "translate(48,-25)")
.attr("height", "50px")
.attr("rx", "15")
.attr("ry", "15")
.style("fill", "rgba(238, 238, 238, 0)")
.style("opacity", "0.9")
.style("stroke",
function(d) {
if (d.children == null && d._children == null)
return "black";
else
return "orange";
})
.style("stroke-width", "2");
nodeEnter.append("g").attr("class", "slicers");
nodeEnter.append("g").attr("class", "lines");
var pieNodes = nodeEnter.select(".slicers").selectAll("path")
.data(function(d, i) {
if (d.id == "NODE1") var value = 0;
else var value = d.parent.value;
value = value == 0 ? 1 : value;
return pie([d, {
value: value
}]);
})
.enter()
.append("svg:path")
.attr("class", "slice")
.attr("fill", function(d, i) {
return color(i);
})
.each(function(d) {
d;
})
.attr('d', arc)
//toolbar
function mouseover(d) {
div.transition()
.duration(500)
.style("opacity", 0.9)
.style("display", "block");
}
function mousemove(d) {
var name = d.name.length > 13 ? d.name.slice("0", "13") : d.name;
div.html("<b>" + d.title + "</b><table>" +
"<tr><td>" + name + ":</td><td>" + parseFloat(d.value).toFixed(1) + "</td></tr></table>")
.style("left", (d3.event.pageX + 50) + "px")
.style("top", (d3.event.pageY + 0) + "px");
}
function mouseout(d) {
div.transition()
.duration(500)
.style("display", "none");
}
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
if (driverTree.hoizMode)
return "translate(" + d.y + "," + d.x + ") rotate(-90)";
else
return "translate(" + d.y + "," + d.x + ") rotate(0)";
});
nodeUpdate.select("circle");
nodeUpdate.select("text");
nodeUpdate.select("rect");
nodeUpdate.select("foreignObject");
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
if (driverTree.hoizMode)
return "translate(" + source.y + "," + source.x + ") rotate(-90)";
else
return "translate(" + source.y + "," + source.x + ") rotate(0)";
})
.remove();
nodeExit.select("circle");
nodeExit.select("text");
nodeExit.select("rect");
nodeExit.select("foreignObject");
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function(d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {
x: source.x,
y: source.y + 100
};
return diagonal({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Function to center node when clicked/dropped so node doesn't get lost when collapsing/moving with large amount of children.
function centerNode(source) {
var scale = driverTree.zoomListener.scale();
var x = -source.y0;
var y = -source.x0;
if (driverTree.hoizMode) {
d3.select("g").transition()
.duration(1)
.attr("transform", "translate(" + width + "," + (height / 2) / 2 + ")scale(" + scale + ")rotate(90,50,50)");
driverTree.zoomListener.translate([width, (height / 2) / 2]);
} else {
d3.select("g").transition()
.duration(1)
.attr("transform", "translate(" + height / 2 + "," + -width / 2 + ")scale(" + scale + ")");
driverTree.zoomListener.translate([height / 2, -width / 2]);
}
driverTree.zoomListener.scale(scale);
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
centerNode(d)
}
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
update(root);
centerNode(root);
以下是我的编辑功能代码
// To make the tree editable
handleEdit: function(evt) {
var that = this;
this.editTree = !this.editTree;
this.treeModel.oData.x = 0;
this.treeModel.oData.y = 0;
this.treeModel.oData.x0 = 0;
this.treeModel.oData.y0 = 0;
this.treeModel.oData.children.forEach(function(d){
d.x = 0; d.y = 0; d.x0 = 0; d.y0 = 0;
var children = (d._children == undefined ? d.children : d._children );
children.forEach(function(a){
a.x = 0; a.y = 0; a.x0 = 0; a.y0 = 0;
});
});
this.drawTree();
},