I am trying to use General Pattern to update my Pack Layout but have not been successful. Below is my fiddle. So when Randomize Data is clicked the data should be updated.
Here is my full fiddle.
function update() {
root = d3.hierarchy(data)
.sum(function(d) {
return d.size;
})
.sort(function(a, b) {
return b.value - a.value;
});
var node = g.selectAll(".node")
.data(pack(root).descendants())
.enter().append("g")
.attr("class", function(d) {
return d.children ? "node" : "leaf node";
})
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
node.append("title")
.text(function(d) {
return d.data.name + "\n" + format(d.value);
});
node.append("circle")
.attr("r", function(d) {
return d.r;
});
node.filter(function(d) {
return !d.children;
}).append("text")
.attr("dy", "0.3em")
.text(function(d) {
return d.data.name.substring(0, d.r / 3);
});
}
Your code only have the "enter" selection. You're missing an "update" selection (and eventually an "exit" selection).
The "update" selection can be something like this:
var nodeUpdate = g.selectAll(".node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});;
var circleUpdate = nodeUpdate.select("circle")
.attr("r", function(d) {
return d.r;
});
Check the fiddle: https://jsfiddle.net/or7pLnjp/
Related
I'm using d3js v3 have a heat map that upon changing a ratio button selection I would switch the data from one dataset to another. The initialization requires a lot of steps e.g.
var svg = d3.select("#myId").append("svg");
...
var heatNode = svg.append("g");
heatNode.selectAll(".cellrect")
.data(data, function(d) { return d.row + ":" + d.col; })
.enter()
.append("rect")
.attr("x", function(d) { return (d.col - 1) * (cellWidth + cellMargin); })
.attr("y", function(d) { return (d.row - 1) * (cellHeight + + cellMargin); })
.attr("class", function(d) { return "cell cell-border cr" + (d.row-1) + " cc" + (d.col-1); })
.attr("width", cellWidth)
.attr("height", cellHeight)
.style("fill", function(d) { return colorScale(d.value); })
.on("mouseover", function(d) {
// highlight text
d3.select(this).classed("cell-hover", true);
d3.selectAll(id + " .rowLabel").classed("text-highlight", function(r, ri) { return ri == (d.row - 1); });
d3.selectAll(id + " .colLabel").classed("text-highlight", function(c, ci) { return ci == (d.col - 1); });
})
.on("mouseout", function(d) {
d3.select(this).classed("cell-hover", false);
d3.selectAll(id + " .rowLabel").classed("text-highlight", false);
d3.selectAll(id + " .colLabel").classed("text-highlight", false);
});
and now I get new data and would like to update only the fill color and nothing else. So I have tried without succcess:
heatNode.selectAll(".cellrect").transition().duration(2000)
.data(newData, function(d) { return d.row + ":" + d.col; })
.style("fill", function(d) { return colorScale(d.value); });
The only way that has worked for me so far is doing an ugly:
heatNode.selectAll("*").transition().duration(2000).remove();
and recreating everything again, however, not even then the transition works for me.
The code seems right but you need to add cellrect class to the first selection if you want to use this class to select the elements again
heatNode.selectAll(".cellrect")
.data(data, function(d) { return d.row + ":" + d.col; })
.enter()
.append("rect")
.attr("x", function(d) { return (d.col - 1) * (cellWidth + cellMargin);})
.attr("y", function(d) { return (d.row - 1) * (cellHeight + + cellMargin); })
.attr("class", function(d) { return "cellrect cell cell-border cr" + (d.row-1) + " cc" + (d.col-1); })
...
This is the code for the Sankey diagram, The first time I added the this when creating node. It is not working.
.on("click", function (d) {
console.log(d);
})
Then I commented d3.behavior.drag(), Then it worked.
This will work.
var node = svg.append("g").selectAll(".node")
.data(energy.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.on("click", function (d) {
console.log(d);
});
// .call(d3.behavior.drag()
// .origin(function(d) { return d; })
// .on("dragstart", function() { this.parentNode.appendChild(this); })
// .on("drag", dragmove));
This will not work.
var node = svg.append("g").selectAll(".node")
.data(energy.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.on("click", function (d) {
console.log(d);
})
.call(d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", function() { this.parentNode.appendChild(this); })
.on("drag", dragmove));
Can someone tell why? How can I add onclick event?
Thanks for your help!!!
I needed my circle pack to highlight matching circles on a mouseover.
was Not sure why the style is not being applied. The function is being hit ok
working fiddle
var node = canvas.selectAll(".node")
.data(nodes)
.enter().append("g")
//.attr("class", ".node")
.attr("class", function(d) { return ".node " + d.AgtName; })
.attr("transform", function (d) { return "translate(" + d.x + ","
+ d.y + ")"; })
.on("mouseover", function(d) { highlight(d.AgtName); })
.on("mouseout", function(d) { highlight(null); });
function highlight(agtName) {
if (agtName == null) d3.selectAll(".node").classed("active",
false);
else d3.selectAll(".node." + agtName).classed("active", true);
console.log('agt: ' + agtName);
}
Moved the fill color to the node instead of the circle. Changed the class from .node to node
var node = canvas.selectAll(".node")
.data(nodes)
.enter().append("g")
//.attr("class", ".node")
.attr("class", function(d) { return "node " + d.AgtName; })
.attr("transform", function (d) { return "translate(" + d.x + ","
+ d.y + ")"; })
.attr("fill", "steelblue")
.on("mouseover", function(d) { highlight(d.AgtName); })
.on("mouseout", function(d) { highlight(null); });
I am building my own sunburst diagram from this example
by adding multiline captions as .
for(i = 0; i < MAX_LINES; i++){
var text = g.append("text")
.attr("transform", function(d) { return "translate(" + getCentroid(d) + ")rotate(" + textRotation(d) + ")"; })
.attr('text-anchor', function (d) { return textRotation(d) > 180 ? "end" : "start"; })
.attr("dx", "0")
.attr("dy", "0em")
.attr("class", function(d) { return setStyle(d); })
.style("fill", function(d) { return setColor(d); })
.style("text-anchor", "middle")
.append("tspan")
.attr("dy", function(d) { return getDY(d, i); } )
.text(function(d) { return getLine(d, i); });
//.text(function(d) { return d.name; });
}
This works absolutely fine on initial state, but when you are
zooming it by clicking on certain partition everything becomes
messy. The script only moves first line element and doesn't
hide other elements shouldn't be on screen.
.duration(500)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
if (e.x >= d.x && e.x < (d.x + d.dx)) {
var arcText = d3.select(this.parentNode).select("text");
arcText.transition().duration(750)
.attr("opacity", 1)
.attr("transform", function(d) { return "translate(" + getCentroid(d) + ")rotate(" + textRotation(d) + ")"; })
.attr('text-anchor', "middle")
}
});
}
});
How I can transform for every partition?
I have tried to do selection by "tspan" or its style class.
Is it possible to completely renew block by reassigning name
and recreating 's
I am using d3.js for bubble chart.its working fine but i need to write custom tool tip for the data which i am showing.currently i just appended one title tag so it just showing one data with tooltip
what if i have more data to show and want to show in form of a table.
Here is my code.
d3.json("data/bubble.json", function(error, root) {
var node = svg.selectAll(".node")
.data(bubble.nodes(classes(root))
.filter(function(d) { return !d.children; }))
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.className + ": " + format(d.value); });
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return color(d.packageName); });
node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.className.substring(0, d.r / 3); });
});