动态数据集的D3 js图例

时间:2018-09-25 17:49:03

标签: javascript d3.js

我想知道如何为数据集添加一个d3 js图例,该图例每次都不具有相同数量的对象,以及如何避免分配不同的颜色,而无需在数据集中明确包含它们。

我所拥有的一个例子是:

var legend = svg.selectAll(".legend")
  .data(tasks)
  .enter()
  .append("g")

  legend.append("rect")
  .attr("fill", function(d){return d.color})
  .attr("width", 10)
  .attr("height", 15)
  .attr("x", -100)
  .attr("y", function(d, i){return 20+20*i})

  legend.append("text")
  .attr("y", function(d, i){return 32+20*i})
  .attr("x", -90)
  .text(function (d) {
       return d.taskName
  });

在此示例中,颜色包含在数据集中,我试图避免这种情况。此外,如果数据集包含更多元素,则图例将溢出或与图表重叠。

我还看到了d3-legend.js,但我最终无法开始工作,但是,我认为可以通过创建颜色域来避免颜色问题,但是我对d3.js相对较新,可以不做。至于重叠/溢出,我一无所知。

The fiddle到上面的示例。

1 个答案:

答案 0 :(得分:0)

您可以通过在两种预定颜色之间的范围内插入colorScale次(数据集的长度)来创建n

const colorScale = d3.scale.linear()
  .domain([1, data.length])
  .interpolate(d3.interpolateHcl)
  .range([d3.rgb(colorA), d3.rgb(colorB)])

以完全相同的方式(确保相同的颜色)创建每个数据元素和每个图例元素时,您都可以从刻度中访问一种颜色

colorScale(i)

关于以最小化重叠/溢出的方式设计图例,可以使用CSS flexbox,column,float(选择您喜欢的)来完成布局。


完整解决方案:

var data = [{
  "first_name": "Daisey"
}, {
  "first_name": "Lowell"
}, {
  "first_name": "Evaleen"
}, {
  "first_name": "Reube"
}, {
  "first_name": "Barnebas"
}, {
  "first_name": "Raddie"
}, {
  "first_name": "Caitlin"
}, {
  "first_name": "Jorry"
}, {
  "first_name": "Ruth"
}, {
  "first_name": "Aldrich"
}]

const legend = d3.select("#legend")
const colorA = "#0000FF"
const colorB = "#7FFF00"

const colorScale = d3.scale.linear().domain([1, data.length])
  .interpolate(d3.interpolateHcl)
  .range([d3.rgb(colorA), d3.rgb(colorB)]);


const legendItem = legend.selectAll('div')
  .data(data)
  .enter()
  .append('div')
  .attr('class', 'legend-item')


legendItem.append('div').attr('class', 'legend-item--color').style('background-color', (d, i) => colorScale(i))

legendItem.append('h3')
  .attr('class', 'legend-item--header')
  .text(d => d.first_name)
#legend {
  display: flex;
  flex-wrap: wrap;
}

.legend-item {
  flex: 50%;
  margin-bottom: 10px;
}

.legend-item--header {
  display: inline-block;
  vertical-align: middle;
  margin: 0 0 0 10px;
}

.legend-item--color {
  display: inline-block;
  width: 30px;
  height: 30px;
  vertical-align: middle;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="legend"></div>

Example block


Updated fiddle