问题
I wanted to hide the outer ring in Sunburst, and I wanted to show it when the user drills down the sunburst. So that I can clearly show the data in outer ring clearly.... Thanks in advance
Here is my code
var width = 700,
height = width,
radius = width / 2,
x = d3.scale.linear().range([0, 2 * Math.PI]),
y = d3.scale.pow().exponent(1.3).domain([0, 1]).range([0, radius]),
padding = 5,
duration = 1000;
color = d3.scale.category20c();
var div = d3.select("#vis");
div.select("svg").remove();
div.select("div").remove();
div.select("p").remove();
div.select("img").remove();
var vis = div.append("svg")
.attr("width", width + padding * 2)
.attr("height", height + (padding * 2) + 2000)
.append("g")
.attr("transform", "translate(" + [radius + padding, radius + padding] + ")");
/*
div.append("p")
.attr("id", "intro")
.text("Click to zoom!");
*/
var partition = d3.layout.partition()
.sort(null)
.value(function(d) { return 5.8 - d.depth; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, d.y ? y(d.y) : d.y); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
var json = JSON.parse(jsonStr);
var nodes = partition.nodes({children: json});
var path = vis.selectAll("path").data(nodes);
path.enter().append("path")
.attr("id", function(d, i) { return "path-" + i; })
.attr("d", arc)
.attr("fill-rule", "evenodd")
.style("fill", colour)
.attr("title",function(d)
{
return d.depth ? d.desc: "";
})
.on("click", nodeClicked);
var text = vis.selectAll("text").data(nodes);
var textEnter = text.enter().append("text")
.style("fill-opacity", 1)
.style("fill", function(d)
{
return brightness(d3.rgb(colour(d))) < 125 ? "#eee" : "#000";
})
.attr("text-anchor", function(d)
{
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
})
.attr("dy", ".2em")
.attr("transform", function(d)
{
var multiline = (d.name || "").split(" ").length > 1,
angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -0.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + padding) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
})
.attr("title",function(d)
{
return d.depth ? d.desc: "";
})
.on("click", showModelDetailsForCriteria);
textEnter.append("tspan")
.attr("x", 0)
.text(function(d) { return d.depth ? d.name.split(" ")[0] : ""; });
textEnter.append("tspan")
.attr("x", 0)
.attr("dy", "1em")
.text(function(d) { return d.depth ? d.name.split(" ")[1] || "" : ""; });
function nodeClicked(d)
{
path.transition()
.duration(duration)
.attrTween("d", arcTween(d));
// Somewhat of a hack as we rely on arcTween updating the scales.
text.style("visibility", function(e)
{
return isParentOf(d, e) ? null : d3.select(this).style("visibility");
})
.transition()
.duration(duration)
.attrTween("text-anchor", function(d)
{
return function()
{
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
};
})
.attrTween("transform", function(d)
{
var multiline = (d.name || "").split(" ").length > 1;
return function()
{
var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -0.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + padding) +
")rotate(" + (angle > 90 ? -180 : 0) + ")";
};
})
.style("fill-opacity", function(e)
{
return isParentOf(d, e) ? 1 : 1e-6;
})
.each("end", function(e)
{
d3.select(this).style("visibility", isParentOf(d, e) ? null : "hidden");
});
}
function isParentOf(p, c)
{
if (p === c) return true;
if (p.children)
{
return p.children.some(function(d)
{
return isParentOf(d, c);
});
}
return false;
}
function colour(d)
{
var nameStr = d.name;
if (d.name == 'Danger')
{
return "red";
}
else if (d.name == 'Stable')
{
return "green";
}
else if ((d.name !== undefined) && (nameStr.indexOf("Need Ana") >= 0))
{
return "orange";
}
else if ((d.name !== undefined) && (nameStr.indexOf("Not Mon") >= 0))
{
return "grey";
}
else
{
if (!d.parent)
{
return "#fff";
}
if (!useRAG)
{
if ((d.data.color !== null) && (d.data.color !== undefined) &&
((d.data.color == "red")||(d.data.color == "green")||(d.data.color == "amber")||(d.data.color == "grey")))
{
return d.data.color;
}
return color((d.children ? d : d.parent).name);
}
if (d.children)
{
var colours = d.children.map(colour);
var childCount = d.children.length;
var hueAddition = 10;
for (var index = 0; index < childCount; index++ )
{
hueAddition += (d3.hsl(colours[index])).h;
}
return d3.hsl((hueAddition) / childCount, (d3.hsl(colours[0])).s * 1.2,
(d3.hsl(colours[0])).l * 1.2);
}
return d.colour || "#fff";
}
}
// Interpolate the scales!
function arcTween(d)
{
var my = maxY(d),
xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, my]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d)
{
return function(t)
{
x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d);
};
};
}
function maxY(d)
{
return d.children ? Math.max.apply(Math, d.children.map(maxY)) : d.y + d.dy;
}
// http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
function brightness(rgb)
{
return rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114;
}
if (top != self) top.location.replace(location);
function showModelDetailsForCriteria(d)
{
var criterions = d.filter.split(",");
var confirmationMessage = "Do you want to view the model list for - ";
var startindex = 0;
if (criterions[startindex] !== null && criterions[startindex] !== undefined)
{
var statusInt = parseInt(criterions[startindex]);
var statusString = "Not Monitered";
if (statusInt === 0)
{
statusString = "Stable";
}
else if (statusInt == 1)
{
statusString = "Need Analysis";
}
else if (statusInt == 2)
{
statusString = "Danger";
}
confirmationMessage += "<BR>Health Status = " + statusString;
startindex++;
}
if (criterions[startindex] !== null && criterions[startindex] !== undefined)
{
confirmationMessage += "<BR>Model Owner = " + criterions[startindex];
startindex++;
}
if (criterions[startindex] !== null && criterions[startindex] !== undefined)
{
confirmationMessage += "<BR>Biz Application = " + criterions[startindex];
startindex++;
}
if (criterions[startindex] !== null && criterions[startindex] !== undefined)
{
confirmationMessage += "<BR>Class of Model = " + criterions[startindex];
startindex++;
}
if (criterions[startindex] !== null && criterions[startindex] !== undefined)
{
confirmationMessage += "<BR>Model Name = " + criterions[startindex];
startindex++;
}
if (criterions[startindex] !== null && criterions[startindex] !== undefined)
{
confirmationMessage += "<BR>Product Type = " + criterions[startindex];
startindex++;
}
app.confirm(confirmationMessage, false,
function()
{
nodeClicked(d);
},
function ()
{
//nodeClicked(d);
});
}
回答1:
Look at this piece of code, you should be able to add the depth for each ring. You should know the max depth of the layout and that gives you your outer ring.
var path = vis.selectAll("path").data(nodes);
path.enter().append("path")
.attr("id", function(d, i) { return "path-" + i; })
.attr("class", function(d) { return "ring_" + d.depth; }) <--- add this line
.attr("d", arc)
.attr("fill-rule", "evenodd")
.style("fill", colour)
.attr("title",function(d)
{
return d.depth ? d.desc: "";
})
.on("click", nodeClicked);
Just in case you find some useful ideas here: http://protembla.com/wheel.html some unfinished viz I played with when I was just learning d3, so quality is not great!
来源:https://stackoverflow.com/questions/22190077/how-to-hide-outer-ring-in-zoomable-sunburst