嗨,我有一个非常基本的D3.js图例
svg.append('g')
.classed('legend-color', true)
.attr('text-anchor', 'start')
.attr('transform', 'translate(20,30)')
.style('font-size', '11px')
.style('fill', 'rgb(0,0,0)')
.call(legendOrdinal);
我想把它分成两半,因为否则,底部的图例单元会干扰我的节点。
所以基本上它将来自
Category A
Category B
Category C
Category D
Category E
Category F
Category G
Category H
到
Category A Category E
Category B Category F
Category C Category G
Category D Category H
答案 0 :(得分:3)
使用一栏图例,您可以使用以下内容轻松定位每个条目:
.attr("transform", function(d,i) { "translate(10," + (i * 20) +")" });
要放置多个列(以及同时放置行),我们需要调整转换的x值并根据列调整y值。最简单的方法可能是对x和y使用以下代码:
x = Math.floor(i/c) * w + tx
y = i % c * h + ty
其中c
是列数,w
是每个图例条目的宽度,tx
是所有图例条目水平转换的基本量,h
是图例条目的高度,ty
是所有图例条目垂直转换的基本量。
您可以使用以下功能来实现上述目标:
function position(d,i) {
var c = 2; // number of columns
var h = 20; // legend entry height
var w = 150; // legend entry width (so we can position the next column)
var tx = 10; // tx/ty are essentially margin values
var ty = 10;
var x = i % c * w + tx;
var y = Math.floor(i / c) * h + ty;
return "translate(" + x + "," + y + ")";
}
var entries = "ABCDEFGHIJ".split("");
var color = d3.schemeCategory10;
var n = Math.round(entries.length/2);
var w = 100;
var h = 20;
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height",200);
var legend = svg.selectAll("g")
.data(entries)
.enter()
.append("g")
.attr("transform", position)
legend.append("text")
.attr("x", 18)
.attr("y", 12)
.text(function(d) { return "Category " + d; });
legend.append("rect")
.attr("width",10)
.attr("height",10)
.attr("fill",function(d,i) { return color[i]; })
function position(d,i) {
var c = 2; // number of columns
var h = 20; // height of each entry
var w = 150; // width of each entry (so you can position the next column)
var tx = 10; // tx/ty are essentially margin values
var ty = 10;
var x = i % c * w + tx;
var y = Math.floor(i / c) * h + ty;
return "translate(" + x + "," + y + ")";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
或者,您可以通过压缩将其缩短:
var entries = "ABCDEFGHIJ".split("");
var color = d3.schemeCategory10;
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height",200);
var legend = svg.selectAll("g")
.data(entries)
.enter()
.append("g")
.attr("transform", function(d,i) {
return "translate(" + (i % 2 * 150 + 10) + "," + (Math.floor(i / 2) * 20 + 10) + ")";
})
legend.append("text")
.attr("x", 18)
.attr("y", 12)
.text(function(d) { return "Category " + d; });
legend.append("rect")
.attr("width",10)
.attr("height",10)
.attr("fill",function(d,i) { return color[i]; })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
如果您希望每列中的条目是连续的,而不是每行中的条目,我们可以对其进行一些修改以指定行数(由所需的列数和图例决定)您拥有的项目:Math.ceil(numberEntries/numberColumns)
。看起来可能像这样:
var entries = "ABCDEFGHIJ".split("");
var color = d3.schemeCategory10;
var n = Math.round(entries.length/2);
var w = 100;
var h = 20;
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height",200);
var legend = svg.selectAll("g")
.data(entries)
.enter()
.append("g")
.attr("transform", position)
legend.append("text")
.attr("x", 18)
.attr("y", 12)
.text(function(d) { return "Category " + d; });
legend.append("rect")
.attr("width",10)
.attr("height",10)
.attr("fill",function(d,i) { return color[i]; })
function position(d,i) {
var c = 3
var r = Math.ceil(entries.length / c);
var h = 20; // height of each entry
var w = 100; // width of each entry (so you can position the next column)
var tx = 10; // tx/ty are essentially margin values
var ty = 10;
var x = Math.floor(i / r) * w + tx;
var y = i % r * h + ty;
return "translate(" + x + "," + y + ")";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
此方法可能导致最后一列只有一个条目,而上面的第一个方法可能只有一行只有一个行。视情况而定,可能更优选
答案 1 :(得分:0)
您可以对transform
属性使用函数,并根据逻辑更改布局。
这是一个简单的例子:
而不是.attr('transform', 'translate(20,30)')
,请输入以下内容:
.attr('transform', function(data, index){
var sections = Math.round((Object.keys(slices).length - 1) / 2);
if(index < sections)
return 'translate(0,0)';
else
return 'translate(80,-40)';
});
这是我写的一个非常简单的逻辑,只是为了向您展示这个想法。我计算一列中会有多少个元素,然后根据其索引更改其每个translate
属性。
这是小提琴:https://jsfiddle.net/nimeshka/wbejmg30/35/
检查上述小提琴中的最后一个代码块以查看此内容。
希望有帮助!