在 D3.js 中,如何创建一个 2 行的水平图例?
这是创建图例的当前 JavaScript 代码:
var legendGroup = svg.append("g")
.attr("transform", "translate("+(width-50)+",30)");
var legend = legendGroup.selectAll(".legend")
.data(nations.map(d=>d.name))
.enter()
.append("g")
.attr("transform", (d,i)=>"translate(0," + 20*i + ")")
var legendRects = legend.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("fill", d=> colorScale(d));
var legendText = legend.append("text")
.attr("x", 14)
.attr("y", 8)
.text(d=>d);
Run Code Online (Sandbox Code Playgroud)
正如您所说,您发布的代码是一列,因为它将图例的每一部分转换为最后一个以下 20 像素:"translate(0," + 20*i + ")"。通过操作 translate 语句,如果您知道数组中有多少个元素,您可以创建一个 2 行图例,即使您不知道,您也可以指定每行中可以有多少个元素。
在下面的代码块中,n指的是一行中应该有多少项itemWidth,每个图例条目宽度的像素值,以及itemHeight高度。
我不知道你有多少传奇物品,但你可以这样设置:
.attr("transform", function(d,i) { return
"translate(" + i%n * itemWidth +
"," +
Math.floor(i/n) * itemHeight + ")"; })
Run Code Online (Sandbox Code Playgroud)
这应该像这样工作:
.attr("transform", function(d,i) { return
"translate(" + i%n * itemWidth +
"," +
Math.floor(i/n) * itemHeight + ")"; })
Run Code Online (Sandbox Code Playgroud)
var data = ["Cat A","Cat B","Cat C", "Cat D", "Dog A", "Dog B", "Dog C", "Dog D"];
var n = data.length/2;
var itemWidth =80;
var itemHeight = 18;
var svg = d3.select("svg");
var color = d3.scale.category10();
var legend = svg.selectAll(".legend")
.data(data)
.enter()
.append("g")
.attr("transform", function(d,i) { return "translate(" + i%n * itemWidth + "," + Math.floor(i/n) * itemHeight + ")"; })
.attr("class","legend");
var rects = legend.append('rect')
.attr("width",15)
.attr("height",15)
.attr("fill", function(d,i) { return color(i); });
var text = legend.append('text')
.attr("x", 15)
.attr("y",12)
.text(function(d) { return d; });Run Code Online (Sandbox Code Playgroud)
编辑:这是根据以下评论移动整个水平图例的片段(在这个狭窄的视图中,使用四行更好地向右侧更好地显示移动):
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="500" height="100"></svg>Run Code Online (Sandbox Code Playgroud)
var data = ["Cat A","Cat B","Cat C", "Cat D", "Dog A", "Dog B", "Dog C", "Dog D"];
var n = data.length/4;
var itemWidth =80;
var itemHeight = 18;
var width = 500;
var svg = d3.select("svg");
var color = d3.scale.category10();
var legendGroup = svg.append("g")
.attr("transform", "translate("+(width-150)+",10)");
var legend = legendGroup.selectAll(".legend")
.data(data)
.enter()
.append("g")
.attr("transform", function(d,i) { return "translate(" + i%n * itemWidth + "," + Math.floor(i/n) * itemHeight + ")"; })
.attr("class","legend");
var rects = legend.append('rect')
.attr("width",15)
.attr("height",15)
.attr("fill", function(d,i) { return color(i); });
var text = legend.append('text')
.attr("x", 15)
.attr("y",12)
.text(function(d) { return d; });Run Code Online (Sandbox Code Playgroud)
const legendData = ['The United States', 'Brazil', 'India', 'China', 'United Arab Emirates'] // The names which you want to appear as legends should be inside this array.
const legend = d3.select('svg')
.append('g')
.attr('transform', 'translate(' + (margin.left + margin.right + 60) + ',' + (margin.top - 20) + ')')
.selectAll('g')
.data(legendData)
.enter()
.append('g');
legend.append('rect')
.attr('fill', (d, i) => color(d)) // const color = d3.scaleOrdinal(d3.schemeCategory10);
.attr('height', 15)
.attr('width', 15);
legend.append('text')
.attr('x', 18)
.attr('y', 10)
.attr('dy', '.15em')
.text((d, i) => d)
.style('text-anchor', 'start')
.style('font-size', 12);
// Now space the groups out after they have been appended:
const padding = 10;
legend.attr('transform', function (d, i) {
return 'translate(' + (d3.sum(legendData, function (e, j) {
if (j < i) { return legend.nodes()[j].getBBox().width; } else { return 0; }
}) + padding * i) + ',0)';
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4792 次 |
| 最近记录: |