d3 - 按周缩放时间

Tim*_*mmo 2 javascript d3.js

我正在使用 d3 在网络中重新创建图表。我有一个在 y 轴上具有适当比例的折线图。我现在需要能够在 x 轴上设置与日期一起使用的比例。

我想要的是能够从总计中打印出日期和星期,类似于 Excel 中的以下示例: Excel 示例

这是我目前得到的: d3 示例

这是我当前的课程:

Chart.js

import React, { Component } from 'react';
import moment from 'moment';
import { scaleLinear, scaleTime } from 'd3-scale';
import { max, extent } from 'd3-array';
import { select } from 'd3-selection';
import { line } from 'd3-shape';
import { axisBottom, axisLeft } from 'd3-axis';

import '../App.css';

const margin = { top: 20, right: 20, bottom: 30, left: 50 };

class Chart extends Component {
  componentDidMount = () => {
    this.createChart();
  }

  componentDidUpdate = () => {
    this.createChart();
  }

  createChart = () => {
    switch (this.props.type) {
      case 'bar': this.createBarChart(); break;
      case 'line-date': this.createDateLineChart(); break;
      default: break;
    }
  }

  createBarChart = () => {
    const node = this.node;
    const dataMax = max(this.props.data);
    const yScale = scaleLinear()
      .domain([0, dataMax])
      .range([0, this.props.size[1]]);

    select(node)
      .selectAll('rect')
      .data(this.props.data)
      .enter()
      .append('rect');

    select(node)
      .selectAll('rect')
      .data(this.props.data)
      .exit()
      .remove();

    select(node)
      .selectAll('rect')
      .data(this.props.data)
      .style('fill', '#fe9922')
      .attr('x', (d, i) => i * 25)
      .attr('y', d => this.props.size[1] - yScale(d))
      .attr('height', d => yScale(d))
      .attr('width', 25);
  }

  createDateLineChart = () => {
    const node = this.node;
    var svg = select(node);

    var width = +svg.attr('width') - margin.left - margin.right;
    var height = +svg.attr('height') - margin.top - margin.bottom;

    var g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');


    var x = scaleTime()
      .rangeRound([0, width]);

    var y = scaleLinear()
      .rangeRound([height, 0]);

    var d3Line = line()
      .x(function (d) { return x(d.date); })
      .y(function (d) { return y(d.number); });

    var data = [];
    for (var item of this.props.data) {
      data.push({
        date: moment(item.date, 'YYYY-MM-DD').toDate(),
        number: +item.number
      });
    }

    x.domain(this.props.xscale !== undefined ? this.props.xscale : extent(data, function (d) { return d.date; }));
    y.domain(this.props.yscale !== undefined ? this.props.yscale : extent(data, function (d) { return d.number; }));

    // X axis
    g.append('g')
      .call(axisLeft(y))
      // Set axis label
      .append('text')
      .attr('fill', '#000000')
      .attr('transform', 'rotate(-90)')
      .attr('transform-y', '-50%')
      .attr('y', -30) // Left
      .attr('x', (height / 2) * -1) // Down
      .attr('font-weight', 'bold')
      .attr('text-anchor', 'center')
      .text(this.props.labels.x);

    // Y axis
    g.append('g')
      .attr('transform', 'translate(0,' + height + ')')
      .call(axisBottom(x))
      // Removes axis line
      // .select('.domain')
      // .remove()
      // Set axis label
      .append('text')
      .attr('fill', '#000000')
      .attr('transform-x', '-50%')
      .attr('y', 30) // Down
      .attr('x', (width / 2)) // Left
      .attr('font-weight', 'bold')
      .attr('text-anchor', 'center')
      .text(this.props.labels.y);

    // Path / Line
    g.append('path')
      .datum(data)
      .attr('fill', 'none')
      .attr('stroke', 'steelblue')
      .attr('stroke-linejoin', 'round')
      .attr('stroke-linecap', 'round')
      .attr('stroke-width', 1.5)
      .attr('d', d3Line);
    // });
  }

  render() {
    return (
      <svg ref={node => this.node = node}
        width={1280}
        height={720} />
    );
  }
}

export default Chart;
Run Code Online (Sandbox Code Playgroud)

我需要做什么才能让 d3 设置比例以便我可以将日期设置为W1 - 08/09/17等?

Ger*_*ado 5

您可以通过操纵轴生成器获得您想要的结果。

首先,要显示每周一个刻度,请使用ticks

.ticks(d3.timeWeek.every(1))
Run Code Online (Sandbox Code Playgroud)

然后,要显示本周之前的周数,请使用以下中的第二个参数tickFormat

.tickFormat(function(d, i) {
    return "W" + (i + 1) + " - " + d3.timeFormat("%d/%m/%y")(d)
});
Run Code Online (Sandbox Code Playgroud)

由于我们每周仅显示一个刻度,因此第二个参数(即每个刻度的索引)将是周数(加 1,因为索引是从零开始的)。

这是一个演示:

.ticks(d3.timeWeek.every(1))
Run Code Online (Sandbox Code Playgroud)
.tickFormat(function(d, i) {
    return "W" + (i + 1) + " - " + d3.timeFormat("%d/%m/%y")(d)
});
Run Code Online (Sandbox Code Playgroud)