gpt4 book ai didi

javascript - D3 中的折线和图例间距

转载 作者:技术小花猫 更新时间:2023-10-29 12:00:47 26 4
gpt4 key购买 nike

我正在使用下面的示例,并希望在饼图之外添加图例,并为文本添加折线,并为每个切片添加计数和百分比。

使用当前代码,当我将鼠标悬停在切片上时,我在饼图中显示了 Pie 和 Text 和 Percentage。

非常感谢您的帮助。谢谢

有人可以帮忙吗,因为我无法前进。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="normalize.css">
<style>
#chart {
height: 360px;
margin: 0 auto; /* NEW */
position: relative;
width: 360px;
}

.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #333;
display: none;
font-size: 12px;
left: 130px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
width: 80px;
z-index: 10;
}

.legend {
font-size: 12px;
}

rect {
cursor: pointer; /* NEW */
stroke-width: 2;
}

rect.disabled { /* NEW */
fill: transparent !important; /* NEW */
}
/* NEW */
h1 { /* NEW */
font-size: 14px; /* NEW */
text-align: center; /* NEW */
}
/* NEW */
</style>
</head>
<body>

<div id="chart"></div>
<script src="Scripts/d3.v3.min.js"></script>
<script>
(function(d3) {
'use strict';

var width = 360;
var height = 360;
var radius = Math.min(width, height) / 2;
var donutWidth = 75;
var legendRectSize = 18;
var legendSpacing = 4;

var color = d3.scale.category20(); //builtin range of colors

var svg = d3.select('#chart')
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + (width / 2) +
',' + (height / 2) + ')');

var arc = d3.svg.arc()
.innerRadius(radius - donutWidth)
.outerRadius(radius);

var pie = d3.layout.pie()
.value(function(d) { return d.count; })
.sort(null);

var tooltip = d3.select('#chart')
.append('div')
.attr('class', 'tooltip');

tooltip.append('div')
.attr('class', 'label');

tooltip.append('div')
.attr('class', 'count');

tooltip.append('div')
.attr('class', 'percent');

d3.csv('weekdays.csv', function(error, dataset) {
dataset.forEach(function(d) {
d.count = +d.count;
d.enabled = true; // NEW
});

var path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) {
return color(d.data.label);
}) // UPDATED (removed semicolon)
.each(function(d) { this._current = d; }); // NEW

path.on('mouseover', function(d) {
var total = d3.sum(dataset.map(function(d) {
return (d.enabled) ? d.count : 0; // UPDATED
}));
var percent = Math.round(1000 * d.data.count / total) / 10;
tooltip.select('.label').html(d.data.label);
tooltip.select('.count').html(d.data.count);
tooltip.select('.percent').html(percent + '%');
tooltip.style('display', 'block');
});

path.on('mouseout', function() {
tooltip.style('display', 'none');
});

/* OPTIONAL
path.on('mousemove', function(d) {
tooltip.style('top', (d3.event.pageY + 10) + 'px')
.style('left', (d3.event.pageX + 10) + 'px');
});
*/

var legend = svg.selectAll('.legend')
.data(color.domain())
.enter()
.append('g')
.attr('class', 'legend')
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing;
var offset = height * color.domain().length / 2;
var horz = -2 * legendRectSize;
var vert = i * height - offset;
return 'translate(' + horz + ',' + vert + ')';
});

legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', color)
.style('stroke', color) // UPDATED (removed semicolon)
.on('click', function(label) { // NEW
var rect = d3.select(this); // NEW
var enabled = true; // NEW
var totalEnabled = d3.sum(dataset.map(function(d) { // NEW
return (d.enabled) ? 1 : 0; // NEW
})); // NEW

if (rect.attr('class') === 'disabled') { // NEW
rect.attr('class', ''); // NEW
} else { // NEW
if (totalEnabled < 2) return; // NEW
rect.attr('class', 'disabled'); // NEW
enabled = false; // NEW
} // NEW

pie.value(function(d) { // NEW
if (d.label === label) d.enabled = enabled; // NEW
return (d.enabled) ? d.count : 0; // NEW
}); // NEW

path = path.data(pie(dataset)); // NEW

path.transition() // NEW
.duration(750) // NEW
.attrTween('d', function(d) { // NEW
var interpolate = d3.interpolate(this._current, d); // NEW
this._current = interpolate(0); // NEW
return function(t) { // NEW
return arc(interpolate(t)); // NEW
}; // NEW
}); // NEW
}); // NEW

legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return d; });

});

})(window.d3);
</script>
</body>
</html>

最佳答案

您可以将图例放在您想要的任何地方,方法是将图例放在一个组中并使用 translate

放置它

首先制作 SVG:

  var s = d3.select('#chart')
.append('svg')
.attr('width', width)
.attr('height', height);

现在创建一个图例组:

  var legend_group = s.append('g').attr('transform',
'translate(' + (width / 3) + ',' + (height / 1.4) + ')');

使用将其翻译到您选择的地方。我已经将它移动到 (width/3, height/1.4)

制作一个将在其中绘制饼图的组。

  var svg = s.append('g')
.attr('transform', 'translate(' + (width / 2) +
',' + (radius) + ')');

让我们为每个切片制作一条折线:此函数将生成与数据集长度一样多的折线。

function makePolyLines() {
var polyline = svg.selectAll("polyline")
.data(pie(dataset), key);

polyline.enter()
.append("polyline");
//hide polyline for which value is 0, a case when legend is clicked.
svg.selectAll("polyline").style("display", function(d) {
if (d.value == 0) {
return "none";
} else {
return "block";
}
});

polyline.transition().duration(1000)
.attrTween("points", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});

polyline.exit()
.remove();
}

同样为标签制作文本。

function makeTexts() {
var text = svg.selectAll(".labels")
.data(pie(dataset), key);

text.enter()
.append("text")
.attr("dy", ".35em")
.classed("labels", true)
.text(function(d) {
return d.data.label + " (" + d.data.count + ")";
});
//hide text for which value is 0, a case when legend is clicked.
svg.selectAll(".labels").style("display", function(d) {
if (d.value == 0) {
return "none";
} else {
return "block";
}
});

text.transition().duration(1000)
.attrTween("transform", function(d) {

this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});

text.exit()
.remove();
}

最后调用这两个函数。

1) 最初是在获取数据之后。

2) 每当单击图例并更新饼图时。

工作代码 here

关于javascript - D3 中的折线和图例间距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37662554/

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