带水平分页的 D3 饼图图例
D3 pie chart legends with horizontal pagination
我有一个要求,如果图例的数量超过两个,我需要显示图例的分页。我正在使用 d3 饼图。任何帮助,将不胜感激。
我发现了类似的东西,但无法使用 d3 版本 5 实现。
我已经修改了您在此 bl.ocks link 中提供的代码。
这是我创建的代码笔 link link。
这里实现的分页可以直接用于d3 v5。问题出在图表上。
var legendCount = dataSet.series.length;
var legendWidth = 10;
var legendSpacing = 6;
var netLegendHeight = (legendWidth + legendSpacing) * legendCount;
var legendPerPage, totalPages, pageNo;
// if (netLegendHeight / height > 1) {
legendPerPage = 2;
totalPages = Math.ceil(legendCount / legendPerPage);
pageNo = 1;
var startIndex = (pageNo - 1) * legendPerPage;
var endIndex = startIndex + legendPerPage;
var seriesSubset = [],
colorSubset = [];
for (var i = 0; i < dataSet.series.length; i++) {
if (i >= startIndex && i < endIndex) {
seriesSubset.push(dataSet.series[i]);
colorSubset.push(colors[i]);
}
}
DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages);
// }
function DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages) {
var legend = svg.selectAll("g.legendg")
.data(seriesSubset)
.enter().append("g")
.attr('class', 'legendg')
.attr("transform", function(d, i) {
return "translate(" + (width - 40) + "," + i * (legendWidth + legendSpacing) + ")";
});
legend.append("rect")
.attr("x", 45)
.attr("width", legendWidth)
.attr("height", legendWidth)
.attr("class", "legend")
.style('fill', function(d, i) {
return colorSubset[i];
});
legend.append("text")
.attr("x", 60)
.attr("y", 6)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d) {
return d;
});
var pageText = svg.append("g")
.attr('class', 'pageNo')
.attr("transform", "translate(" + (width + 7.5) + "," + (legendPerPage + 1) * (legendWidth + legendSpacing) + ")");
pageText.append('text').text(pageNo + '/' + totalPages)
.attr('dx', '.25em');
var prevtriangle = svg.append("g")
.attr('class', 'prev')
.attr("transform", "translate(" + (width + 5) + "," + (legendPerPage + 1.5) * (legendWidth + legendSpacing) + ")")
.on('click', prevLegend)
.style('cursor', 'pointer');
var nexttriangle = svg.append("g")
.attr('class', 'next')
.attr("transform", "translate(" + (width + 20) + "," + (legendPerPage + 1.5) * (legendWidth + legendSpacing) + ")")
.on('click', nextLegend)
.style('cursor', 'pointer');
nexttriangle.append('polygon')
.style('stroke', '#000')
.style('fill', '#000')
.attr('points', '0,0, 10,0, 5,5');
prevtriangle.append('polygon')
.style('stroke', '#000')
.style('fill', '#000')
.attr('points', '0,5, 10,5, 5,0');
if (pageNo == totalPages) {
nexttriangle.style('opacity', '0.5')
nexttriangle.on('click', '')
.style('cursor', '');
} else if (pageNo == 1) {
prevtriangle.style('opacity', '0.5')
prevtriangle.on('click', '')
.style('cursor', '');
}
}
function prevLegend() {
pageNo--;
svg.selectAll("g.legendg").remove();
svg.select('.pageNo').remove();
svg.select('.prev').remove();
svg.select('.next').remove();
var startIndex = (pageNo - 1) * legendPerPage;
var endIndex = startIndex + legendPerPage;
var seriesSubset = [],
colorSubset = [];
for (var i = 0; i < dataSet.series.length; i++) {
if (i >= startIndex && i < endIndex) {
seriesSubset.push(dataSet.series[i]);
colorSubset.push(colors[i]);
}
}
DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages);
}
function nextLegend() {
pageNo++;
svg.selectAll("g.legendg").remove();
svg.select('.pageNo').remove();
svg.select('.prev').remove();
svg.select('.next').remove();
var startIndex = (pageNo - 1) * legendPerPage;
var endIndex = startIndex + legendPerPage;
var seriesSubset = [],
colorSubset = [];
for (var i = 0; i < dataSet.series.length; i++) {
if (i >= startIndex && i < endIndex) {
seriesSubset.push(dataSet.series[i]);
colorSubset.push(colors[i]);
}
}
DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages);
}
这是带分页的最终饼图的图像:
我有一个要求,如果图例的数量超过两个,我需要显示图例的分页。我正在使用 d3 饼图。任何帮助,将不胜感激。 我发现了类似的东西,但无法使用 d3 版本 5 实现。
我已经修改了您在此 bl.ocks link 中提供的代码。
这是我创建的代码笔 link link。
这里实现的分页可以直接用于d3 v5。问题出在图表上。
var legendCount = dataSet.series.length;
var legendWidth = 10;
var legendSpacing = 6;
var netLegendHeight = (legendWidth + legendSpacing) * legendCount;
var legendPerPage, totalPages, pageNo;
// if (netLegendHeight / height > 1) {
legendPerPage = 2;
totalPages = Math.ceil(legendCount / legendPerPage);
pageNo = 1;
var startIndex = (pageNo - 1) * legendPerPage;
var endIndex = startIndex + legendPerPage;
var seriesSubset = [],
colorSubset = [];
for (var i = 0; i < dataSet.series.length; i++) {
if (i >= startIndex && i < endIndex) {
seriesSubset.push(dataSet.series[i]);
colorSubset.push(colors[i]);
}
}
DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages);
// }
function DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages) {
var legend = svg.selectAll("g.legendg")
.data(seriesSubset)
.enter().append("g")
.attr('class', 'legendg')
.attr("transform", function(d, i) {
return "translate(" + (width - 40) + "," + i * (legendWidth + legendSpacing) + ")";
});
legend.append("rect")
.attr("x", 45)
.attr("width", legendWidth)
.attr("height", legendWidth)
.attr("class", "legend")
.style('fill', function(d, i) {
return colorSubset[i];
});
legend.append("text")
.attr("x", 60)
.attr("y", 6)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d) {
return d;
});
var pageText = svg.append("g")
.attr('class', 'pageNo')
.attr("transform", "translate(" + (width + 7.5) + "," + (legendPerPage + 1) * (legendWidth + legendSpacing) + ")");
pageText.append('text').text(pageNo + '/' + totalPages)
.attr('dx', '.25em');
var prevtriangle = svg.append("g")
.attr('class', 'prev')
.attr("transform", "translate(" + (width + 5) + "," + (legendPerPage + 1.5) * (legendWidth + legendSpacing) + ")")
.on('click', prevLegend)
.style('cursor', 'pointer');
var nexttriangle = svg.append("g")
.attr('class', 'next')
.attr("transform", "translate(" + (width + 20) + "," + (legendPerPage + 1.5) * (legendWidth + legendSpacing) + ")")
.on('click', nextLegend)
.style('cursor', 'pointer');
nexttriangle.append('polygon')
.style('stroke', '#000')
.style('fill', '#000')
.attr('points', '0,0, 10,0, 5,5');
prevtriangle.append('polygon')
.style('stroke', '#000')
.style('fill', '#000')
.attr('points', '0,5, 10,5, 5,0');
if (pageNo == totalPages) {
nexttriangle.style('opacity', '0.5')
nexttriangle.on('click', '')
.style('cursor', '');
} else if (pageNo == 1) {
prevtriangle.style('opacity', '0.5')
prevtriangle.on('click', '')
.style('cursor', '');
}
}
function prevLegend() {
pageNo--;
svg.selectAll("g.legendg").remove();
svg.select('.pageNo').remove();
svg.select('.prev').remove();
svg.select('.next').remove();
var startIndex = (pageNo - 1) * legendPerPage;
var endIndex = startIndex + legendPerPage;
var seriesSubset = [],
colorSubset = [];
for (var i = 0; i < dataSet.series.length; i++) {
if (i >= startIndex && i < endIndex) {
seriesSubset.push(dataSet.series[i]);
colorSubset.push(colors[i]);
}
}
DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages);
}
function nextLegend() {
pageNo++;
svg.selectAll("g.legendg").remove();
svg.select('.pageNo').remove();
svg.select('.prev').remove();
svg.select('.next').remove();
var startIndex = (pageNo - 1) * legendPerPage;
var endIndex = startIndex + legendPerPage;
var seriesSubset = [],
colorSubset = [];
for (var i = 0; i < dataSet.series.length; i++) {
if (i >= startIndex && i < endIndex) {
seriesSubset.push(dataSet.series[i]);
colorSubset.push(colors[i]);
}
}
DrawLegendSubset(seriesSubset, colorSubset, legendPerPage, pageNo, totalPages);
}
这是带分页的最终饼图的图像: