D3.js实现图表图例单行排列的问题求助
解决D3.js图例逐行显示无法横向排列的问题
我想用rect和text元素给图表加一个包含4个项的单行图例,但代码运行后图例还是逐行显示,加上指定的CSS样式也没解决问题。
问题原因
- SVG中的
<g>元素是SVG内部容器,CSS的display: inline-block对它不生效,所以加了也没用 - 当前代码给每个图例
<g>设置的transform是垂直方向偏移(translate(5, i*22)),每个图例项往下偏移22px,自然是垂直排列
修改方案
要实现单行横向排列,只需调整以下几点:
- 扩大SVG宽度,足够容纳4个横向排列的图例项
- 将
transform的偏移方向从垂直改为水平 - 缩小SVG高度,适配单行内容的高度
- 可以删除无效的
.legendCSS样式
修改后的核心代码
var ChartId = '#' + Id; var LegendId = '#' + Id + 'Legend'; var size = 20; var color = d3.scaleOrdinal() .range(['#1A9AD4', '#10B981', '#F59E0B', '#EF4444', '#bf6fe7', '#eb5b5b', '#607d8b', '#80B300', '#809900', '#E6B3B3', '#6680B3', '#66991A', '#FF99E6', '#CCFF1A', '#FF1A66', '#E6331A', '#33FFCC', '#66994D', '#B366CC', '#4D8000', '#B33300', '#CC80CC', '#66664D', '#991AFF', '#E666FF', '#4DB3FF', '#1AB399', '#E666B3', '#33991A', '#CC9999', '#B3B31A', '#00E680', '#4D8066', '#809980', '#E6FF80', '#1AFF33', '#999933', '#FF3380', '#CCCC00', '#66E64D', '#4D80CC', '#9900B3', '#E64D66', '#4DB380', '#FF4D4D', '#99E6E6', '#6666FF' ]); $(LegendId).remove(); $(ChartId).parent().append('<div id="' + Id + 'Legend" style="width:15%"></div>'); var StatusAccessor = function (d) { return d.key[1]; } var filteredData = Grps; //.all(); var Status = d3.set(filteredData.map(StatusAccessor)).values(); // 修改SVG宽高:扩大宽度容纳横向项,缩小高度适配单行 var svg2 = d3.select(LegendId) .append("svg") .attr("width", 320) .attr("height", 40); var legend = svg2.selectAll(".legend") .data(SortInOrder(Status.slice().reverse(), SortArray)) .enter().append("g") .attr("class", "legend") // 把垂直偏移改成水平偏移:i*80控制每个项的横向间距 .attr("transform", function (d, i) { return "translate(" + i * 80 + ", 5)"; }); legend.append("rect") .attr("x", 2) .attr("y", 0) // 微调y轴位置,让方块在SVG中居中 .attr("width", size) .attr("height", size) .style("fill", function (d) { return color(d) }) legend.append("text") .attr("x", 28) .attr("y", 12) // 微调y轴位置,让文字和方块垂直居中对齐 .text(function (d) { return d.replace(/ *\([^)]*\) */g, "") }) .attr("text-anchor", "left") .style("alignment-baseline", "middle")
说明
- 修改
transform的偏移逻辑后,4个图例项会横向排列在一行 - 原来的
.legendCSS样式可以直接删除,因为对SVG的<g>元素完全无效
内容的提问来源于stack exchange,提问作者Lim
相关产品推荐
相关产品推荐

