user2699674
user2699674

Reputation: 1

D3 overlapping labels in partition chart

I have been basically trying to implement the zoomable partition chart for depicting the budger drill down.My problem is that I want to hide the lowest parition and shown only when the parent partition is clicked or displayed in zoom.

When all the lowest partitions are displayed they are overlapped and the text is also over lapped.I want them to be displayed only when clicked on the third partition.

If this is not possible i want atleast the text withint the lower partition to be hidden until its zoomed . Is there a way that this can be achieved. I have been trying to use opacity but it doesn't work Below is the piece of my implementations

function d3ChartGeneration(){
w = 900;
h = 600;

h = 900;
x = d3.scale.linear().range([0, w]);
y = d3.scale.linear().range([0, h]);




vis = d3.select("#budgetDrillDown").append("div")
.attr("class", "chart")
.style("width", w + "px")
.style("height", h + "px")
.append("svg:svg")
.attr("width", w)
.attr("height", h);

partition = d3.layout.partition()
.value(function(d) { return d.size; })
.sort(function(a, b) {   return    a.name.toLowerCase().localeCompare(b.name.toLowerCase()); });

chartGeneration();
}

function chartGeneration(){

var root=JSON.parse(jsonString);


g = vis.selectAll("g")
.data(partition.nodes(root))
.enter().append("svg:g")
.attr("transform", function(d) {  return "translate(" + x(d.y) + "," + y(d.x) + ")"; })
.on("click", click);


kx = w / root.dx;
ky = h / 1;


g.append("svg:rect")
.attr("width", root.dy * kx)
.attr("height", function(d) { return d.dx * ky; })
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.style("fill", function (d) { return d3.rgb(d.color); });
//.filter(function(d) { return d.depth > 2; })
//.style("display", "none");





g.append("svg:text")
.attr("transform", transform)
.attr("dy", ".20em")
.style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; })
.append("tspan")
.attr("x","0")
.attr("y","-0.5")
.text(function(d) { return d.name; })
//.style( "display",function(d) { if( d.depth > 1)  return "none"; })
.append("tspan")
.attr("x","0")
.attr("y","12")
.text(function(d) { return ((d.budget/1000000).toFixed(2)+' M'); });
//.style( "display",function(d) { if( d.depth > 1)  return "none"; });


d3.select("window")
.on("click", function() { click(root); });
}

function click(d) {

if (!d.children) return;

kx = (d.y ? w - 40 : w) / (1 - d.y);
ky = h / d.dx;
x.domain([d.y, 1]).range([d.y ? 40 : 0, w]);
y.domain([d.x, d.x + d.dx]);

var t = g.transition()
.duration(d3.event.altKey ? 7500 : 750)
.attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; });


t.select("rect")
.attr("width", d.dy * kx)
.attr("height", function(d) { return d.dx * ky; })
.style( "display",function(d) { if( d.depth > 2)  return "";});



t.select("text")
.attr("transform", transform)
.style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; });
//.style("display", "inherit");
d3.event.stopPropagation();
}

function transform(d) {
return "translate(8," + d.dx * ky / 2 + ")";
}

Upvotes: 0

Views: 1355

Answers (1)

Phuoc Do
Phuoc Do

Reputation: 1344

You are displaying two labels stacked on top of each other. So you need to half your opacity check:

return d.dx * ky / 2 > 12 ? 1 : 0;

or double:

return d.dx * ky > 24 ? 1 : 0;

Here's the code:

http://vida.io/documents/dg3izzdpu7K4SrG6c

Upvotes: 2

Related Questions