使用D3.js v4的基本线图(非v3)

时间:2017-04-14 03:39:34

标签: typescript d3.js

我很难找到一个没有在 D3.js v4 中使用日期的折线图示例,这主要是因为我不确定如何使用d3.scaleOrdinal()创建xAxis,因为当我尝试执行此操作时出现此错误(在TypeScript中):

let xScale = d3.scaleOrdinal().domain(data.map(d => d.label)).range([0, width]);
svg.append('g') // x axis
  .attr('transform', `translate(${margin.left}, ${margin.top + height})`)
  .call(d3.axisBottom(xScale)); // <-- ERROR HERE


错误:

Argument of type 'ScaleOrdinal<string, {}>' is not assignable to parameter of type 'AxisScale<string>'

有关如何使用此数据创建折线图的任何超级基本示例?:

[{label: 'A', value: 3}, {label: 'B', value: 4}, {label: 'C', value: 2}]

感谢。

1 个答案:

答案 0 :(得分:3)

使用d3版本4.5 - http://codepen.io/marcobiedermann/pen/GWGJvM

查看这个简单的折线图示例

我将它分叉并重新设计了您的数据 - http://codepen.io/levvsha/pen/gWbXdm

const defaults = {
  width : 500,
  height: 370,
  margin: {
    top   : 15,
    right : 5,
    bottom: 35,
    left  : 60
  },
  axis: true,
  axisPadding: 5,
  xTicks: 3,
  yTicks: 3,
  lineCurve: d3.curveLinear
};

class LineChart {

  constructor(element, options) {
    Object.assign(this, defaults, options);

    this.element = element;
    this.init();
  }

  init() {
    const { margin } = this;
    const [ innerWidth, innerHeight ] = this.dimensions();

    const svg = this.svg = d3.select(this.element)
      .append('svg')
        .attr('width', this.width)
        .attr('height', this.height)
      .append('g')
        .attr('transform', `translate(${margin.left}, ${margin.top})`)

    const scaleX = this.scaleX = d3.scaleOrdinal()
      .range([0, innerWidth/2, innerWidth]);

    const scaleY = this.scaleY = d3.scaleLinear()
      .range([innerHeight, 0]);

    const xAxis = this.xAxis = d3.axisBottom(scaleX)
      .ticks(3)
      .tickValues(['A', 'B', 'C'])
      .tickPadding(8);

    const yAxis = this.yAxis = d3.axisLeft(scaleY)
      .ticks(this.yTicks)
      .tickPadding(8);

    svg
      .append('g')
        .attr('class', 'chart__axis chart__axis--x')
        .attr('transform', `translate(0, ${innerHeight + this.axisPadding})`)
        .call(xAxis);

    svg
      .append('g')
        .attr('class', 'chart__axis chart__axis--y')
        .attr('transform', `translate(${-this.axisPadding}, 0)`)
        .call(yAxis);

    svg
      .append('path')
        .attr('class', 'chart__line')

    this.line = d3.line()
      .curve(this.lineCurve)
      .x(data => scaleX(data.label))
      .y(data => scaleY(data.value));
  }

  dimensions() {
    const { margin } = this;

    return [
      this.width - margin.left - margin.right,
      this.height - margin.top - margin.bottom
    ];
  }

  renderAxis(data, options) {
    let { svg } = this;

    svg = options.animate ? svg.transition() : svg;

    svg
      .select('.chart__axis--x')
      .call(this.xAxis);

    svg
      .select('.chart__axis--y')
      .call(this.yAxis);
  }

  renderLine(data, options) {
    this.svg
      .select('.chart__line')
      .data([data])
      .transition()
      .attr('d', this.line);
  }

  render(data, options = {}) {
    this.scaleX.domain(data.map(data => data.label));
    this.scaleY.domain(d3.extent(data, data => data.value));

    if (this.axis) {
      this.renderAxis(data, options);
    }

    this.renderLine(data, options);
  }
}

const lineChart = new LineChart('.js-line-chart');

lineChart.render([{label: 'A', value: 3}, {label: 'B', value: 4}, {label: 'C', value: 2}]);