如何按序使用d3.symbols

时间:2018-11-20 23:55:01

标签: javascript d3.js svg

TL; DR:如何在d3.symbols上获得scaleOrdinal?

我希望将d3.symbols用于有序刻度,该刻度对应于某些数据的分类属性。

  d3。符号      

一个数组,其中包含所有内置符号类型的集合:圆形,十字形,菱形,正方形,星形,三角形和星形。如果您希望对分类数据使用形状编码,则对于构造序数范围的范围很有用。

这是我认为可行的方法:

var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');

var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];

var shape = d3.scaleOrdinal(d3.symbols);

var s = g.selectAll('.symbol').data(data);

/* Does not render */
s.enter()
 .append('path')
 .attr('d', d => shape(d.type))
 .attr('x', (d, i) => i * 20)
 .attr('y', 50);

/* Sanity Check: Properly renders */
s.enter()
 .append('circle')
 .attr('r',7)
 .attr('cx', (d, i) => (i+1)*20)
 .attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>

(或者参见fiddle)。

不幸的是,以上操作失败并显示:

Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "[object Object]".

很显然shape(d.type)没有返回有效路径。实际上,它返回的是一个带有单个名为draw的函数的对象,即它看起来像{ draw: function() { ... } },大概是指this draw method。不幸的是,调用该draw方法也不会产生有效路径。

1 个答案:

答案 0 :(得分:2)

您缺少符号生成器本身...

var symbol = d3.symbol();

...,您将输入以下内容:

s.enter()
    .append('path')
    .attr('d', d => symbol.type(shape(d.type))())
    //etc...

另外,<path>个没有xy属性。

以下是具有这些更改的代码:

var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');

var data = [{
  type: 'a'
}, {
  type: 'a'
}, {
  type: 'a'
}, {
  type: 'b'
}, {
  type: 'b'
}, {
  type: 'c'
}];

var shape = d3.scaleOrdinal(d3.symbols);

var symbol = d3.symbol();

var s = g.selectAll('.symbol').data(data);

/* Does not render */
s.enter()
  .append('path')
  .attr('d', d => symbol.type(shape(d.type))())
  .attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
  .attr('fill', 'black');

/* Properly renders */
s.enter()
  .append('circle')
  .attr('r', 7)
  .attr('cx', (d, i) => (i + 1) * 20)
  .attr('cy', 100)
  .attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>