gpt4 book ai didi

javascript - D3.JS 向下钻取饼图中不显示部分文本标签

转载 作者:行者123 更新时间:2023-11-27 23:06:35 24 4
gpt4 key购买 nike

我想使用“D3.JS”开发“向下钻取”“饼图”。我找到了下面的示例,非常适合我使用。

D3 Js sample drill down pie chart

上面的示例非常适合我。

此外,从示例钻取饼图来看,我想将文本标签放置在饼图划分的每个部分中。

我跟踪了很多样本​​,

  1. Sample 1 - pie chart with section text label

  2. Sample 2 - JSFiddle - pie chart with section text label

基于上面在饼图部分中放置文本标签的示例,我按照下面的代码,尝试添加示例“var dataSet”,“var arcs = svg.selectAll(“g.slice”)”代码。但是,当我执行该程序时,它不会在饼图中每个部分的中心显示任何文本标签。

有人可以指导我解决这个问题吗?

    <!doctype html>
<html>
<head>
<head>
<meta charset="utf-8">
<title>Drill down pie chart test</title>
<script type="text/javascript" src="http://d3js.org/d3.v2.min.js?2.9.6"></script>
<style type="text/css">
body {
text-align: center;
padding: 50px;
font-family: "Helvetica Neue",Arial,Sans-serif;
font-weight: 200;
color: #333;
}
.header {
font-size: 20px;
}
.sector {
cursor: pointer;
}
.slice text {
font-size: 16pt;
font-family: Arial;
}

</style>
</head>
<body>
<script type="text/javascript">


// Globals
var width = 500,
height = 400,
margin = 50,
radius = Math.min(width - margin, height - margin) / 2,
// Pie layout will use the "val" property of each data object entry
pieChart = d3.layout.pie().sort(null).value(function(d){return d.val;}),
arc = d3.svg.arc().outerRadius(radius),
MAX_SECTORS = 15, // Less than 20 please
colors = d3.scale.category20();

var dataSet = [
{"legendLabel":"One", "magnitude":20},
{"legendLabel":"Two", "magnitude":40},
{"legendLabel":"Three", "magnitude":50},
{"legendLabel":"Four", "magnitude":16},
{"legendLabel":"Five", "magnitude":50},
{"legendLabel":"Six", "magnitude":8},
{"legendLabel":"Seven", "magnitude":30}];

//mydata = {"Medical", "Agriculture", "Security"};

var st = {};
st.data = [{"label":"less than a week","value":169,"pos":0},{"label":"1 week - 30 days","value":1,"pos":1},{"label":"30 - 90 days","value":22,"pos":2},{"label":"90 - 180 days","value":35,"pos":3},{"label":"180 days - 1 year","value":47,"pos":4},{"label":"more than 1 year","value":783,"pos":5}] ;


// Synthetic data generation ------------------------------------------------
var data = [];
var numSectors = 8; //Math.ceil(Math.random()*MAX_SECTORS);
for(i = -1; i++ < numSectors; ) {
var children = [];
var numChildSectors = Math.ceil(Math.random()*MAX_SECTORS);
var color = colors(i);
for( j=-1; j++ < numChildSectors; ){

// Add children categories with shades of the parent color
children.push(
{ cat: "cat"+((i+1)*100+j),
val: Math.random(),
color: d3.rgb(color).darker(1/(j+1))
});
}
data.push({
cat: "cat"+i,
val: Math.random(),
color: color,
children: children});
}
// --------------------------------------------------------------------------


// SVG elements init
var svg = d3.select("body").append("svg").data([dataSet]).attr("width", width).attr("height", height),
defs = svg.append("svg:defs"),
// .data(pieChart)

// Declare a main gradient with the dimensions for all gradient entries to refer
mainGrad = defs.append("svg:radialGradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("cx", 0).attr("cy", 0).attr("r", radius).attr("fx", 0).attr("fy", 0)
.attr("id", "master"),
// The pie sectors container
arcGroup = svg.append("svg:g")
.attr("class", "arcGroup")
.attr("filter", "url(#shadow)")
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")"),
// Header text
header = svg.append("text").text("Biotechnology")
.attr("transform", "translate(10, 20)").attr("class", "header");

//svg.append("text").attr("text-anchor", "middle").text("$" + "sample"),
//svg.append("text").text("sample").attr("text-anchor", "middle")

/*svg.append("text")
.attr("transform", "translate(" + arcGroup.centroid(d) + ")")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("sample");
*/

// Declare shadow filter
var shadow = defs.append("filter").attr("id", "shadow")
.attr("filterUnits", "userSpaceOnUse")
.attr("x", -1*(width / 2)).attr("y", -1*(height / 2))
.attr("width", width).attr("height", height);
shadow.append("feGaussianBlur")
.attr("in", "SourceAlpha")
.attr("stdDeviation", "4")
.attr("result", "blur");
shadow.append("feOffset")
.attr("in", "blur")
.attr("dx", "4").attr("dy", "4")
.attr("result", "offsetBlur");
shadow.append("feBlend")
.attr("in", "SourceGraphic")
.attr("in2", "offsetBlur")
.attr("mode", "normal");

/* var arcs = svg.selectAll("g.slice")

arcs.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.value; });
*/



// Redraw the graph given a certain level of data
function updateGraph(cat){
var currData = data;

// Simple header text
if(cat != undefined){
currData = findChildenByCat(cat);
d3.select(".header").text("Biotechnology → "+cat);
} else {
d3.select(".header").text("Biotechnology");
}


// Create a gradient for each entry (each entry identified by its unique category)
var gradients = defs.selectAll(".gradient").data(currData, function(d){return d.cat;});
gradients.enter().append("svg:radialGradient")
.attr("id", function(d, i) { return "gradient" + d.cat; })
.attr("class", "gradient")
.attr("xlink:href", "#master");

gradients.append("svg:stop").attr("offset", "0%").attr("stop-color", getColor );
gradients.append("svg:stop").attr("offset", "90%").attr("stop-color", getColor );
gradients.append("svg:stop").attr("offset", "100%").attr("stop-color", getDarkerColor );


/*var arcs = defs.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class","slice");
arcs.append("svg:text").attr("transform", function(d){
d.innerRadius = 0;
d.outerRadius = r;
return "translate(" + arc.centroid(d) + ")";}).attr("text-anchor", "middle").text( function(d, i) {
return (data[i].value / tot ) * 100 > 10 ? ((data[i].value / tot ) * 100).toFixed(1) + "%" : "";
}
).attr("fill","#fff")
.classed("slice-label",true);
*/

// Create a sector for each entry in the enter selection
var paths = arcGroup.selectAll("path")
.data(pieChart(currData), function(d) {return d.data.cat;} );
paths.enter().append("svg:path").attr("class", "sector");

// Each sector will refer to its gradient fill
paths.attr("fill", function(d, i) { return "url(#gradient"+d.data.cat+")"; })
.transition().duration(1000).attrTween("d", tweenIn).each("end", function(){
this._listenToEvents = true;
});

// Mouse interaction handling
paths.on("click", function(d){
if(this._listenToEvents){
// Reset inmediatelly
d3.select(this).attr("transform", "translate(0,0)")
// Change level on click if no transition has started
paths.each(function(){
this._listenToEvents = false;
});
updateGraph(d.data.children? d.data.cat : undefined);
}
})
.on("mouseover", function(d){
// Mouseover effect if no transition has started
if(this._listenToEvents){
// Calculate angle bisector
var ang = d.startAngle + (d.endAngle - d.startAngle)/2;
// Transformate to SVG space
ang = (ang - (Math.PI / 2) ) * -1;

// Calculate a 10% radius displacement
var x = Math.cos(ang) * radius * 0.1;
var y = Math.sin(ang) * radius * -0.1;

d3.select(this).transition()
.duration(250).attr("transform", "translate("+x+","+y+")");
}
})
.on("mouseout", function(d){
// Mouseout effect if no transition has started
if(this._listenToEvents){
d3.select(this).transition()
.duration(150).attr("transform", "translate(0,0)");
}
});


// Collapse sectors for the exit selection
paths.exit().transition()
.duration(1000)
.attrTween("d", tweenOut).remove();

// NEWLY ADDED START

// Select all <g> elements with class slice (there aren't any yet)
var arcs = svg.selectAll("g.slice")
// Associate the generated pie data (an array of arcs, each having startAngle,
// endAngle and value properties)
.data(pie)
// This will create <g> elements for every "extra" data element that should be associated
// with a selection. The result is creating a <g> for every object in the data array
.enter()
// Create a group to hold each slice (we will have a <path> and a <text>
// element associated with each slice)
.append("svg:g")
.attr("class", "slice"); //allow us to style things in the slices (like text)

arcs.append("svg:path")
//set the color for each slice to be chosen from the color function defined above
.attr("fill", function(d, i) { return color(i); } )
//this creates the actual SVG path using the associated data (pie) with the arc drawing function
.attr("d", arc);

// Add a legendLabel to each arc slice...
arcs.append("svg:text")
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius + 50; // Set Outer Coordinate
d.innerRadius = outerRadius + 45; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle") //center the text on it's origin
.style("fill", "Purple")
.style("font", "bold 12px Arial")
<!-- .text(function(d, i) { return dataSet[i].legendLabel; }); //get the label from our original dat -->
.text(function(d, i) { return "Test"; }); //get the label from our original dat

// Add a magnitude value to the larger arcs, translated to the arc centroid and rotated.
arcs.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
//.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; })
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius; // Set Outer Coordinate
d.innerRadius = outerRadius/2; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")";
})
.style("fill", "White")
.style("font", "bold 12px Arial")
.text(function(d) { return d.data.magnitude; });

function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
// END
}


// "Fold" pie sectors by tweening its current start/end angles
// into 2*PI
function tweenOut(data) {
data.startAngle = data.endAngle = (2 * Math.PI);
var interpolation = d3.interpolate(this._current, data);
this._current = interpolation(0);
return function(t) {
return arc(interpolation(t));
};
}


// "Unfold" pie sectors by tweening its start/end angles
// from 0 into their final calculated values
function tweenIn(data) {
var interpolation = d3.interpolate({startAngle: 0, endAngle: 0}, data);
this._current = interpolation(0);
return function(t) {
return arc(interpolation(t));
};
}


// Helper function to extract color from data object
function getColor(data, index){
return data.color;
}


// Helper function to extract a darker version of the color
function getDarkerColor(data, index){
return d3.rgb(getColor(data, index)).darker();
}


function findChildenByCat(cat){
for(i=-1; i++ < data.length - 1; ){
if(data[i].cat == cat){
return data[i].children;
}
}
return data;
}
//.text(function(d, i) { return categorydata[i].label; });
// Start by updating graph at root level
updateGraph();

</script>
<!-- <p>Drill down pie chart test by Marc Baiges Camprubí <a href="mailto:marcbc@gmail.com">(marcbc@gmail.com)</a> in D3.js -->
</body>
</html>

最佳答案

不要这样做:

var arcs = svg.selectAll("g.slice")

这样做

var arcs = arcGroup.selectAll("g.slice")

原因以便文本标签和饼图的路径都在同一组中。

给出适当的内半径和外半径,以便将标签放置在中心(以便根据圆弧的新内外半径计算质心)

arcs.append("svg:text")
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = radius - 20; // Set Outer Coordinate
d.innerRadius = radius - 100; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")";
})

接下来在文本中给出正确的数据:

      .text(function(d, i) { return "Test"; }); //get the label from our original data

这样做

       .text(function(d, i) { return d.data.cat; }); //get the label from our original data

工作代码here

关于javascript - D3.JS 向下钻取饼图中不显示部分文本标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36527029/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com