D3 v4条形图显示1个像素宽的条形图

时间:2018-02-12 16:51:08

标签: dc.js

我是所有D3 /反应编码的新手。我正在将D3 v3示例转换为D3 v4(React-DC)。我能够转换饼图和行图。但我被困在条形图和区域图表中。这似乎是一个小问题,因为我可以看到渲染的图表,但有以下问题(对于冗长的内容提前抱歉):

  1. 条形图:条形宽度为1像素。我查了DC js FAQ page in github,他们说我必须设置xUnits。但是,我已经定义了xUnits,但它仍然无法工作。

  2. 面积图(已堆叠):仅显示一个?我没有看到剩下的筹码。

  3. 我转换了这个有效的d3.js v3示例

    <BarChart
      dimension={byYear}
      group={byYearGroup}
      x={d3.time.scale()}
      renderHorizontalGridLines={true}
      elasticX={true}
      xUnits={d3.time.years}
      ordinalColors={colors}
    />
    
    <AreaChart
      dimension={byYear}
      group={rockByYearGroup}
      x={d3.time.scale()}
      renderHorizontalGridLines={true}
      elasticX={true}
      xUnits={d3.time.years}
      renderArea={true}
      stack={[popByYearGroup, funkSoulByYearGroup, electroByYearGroup, hipHopByYearGroup]}
      xyTipsOn={true}
      brushOn={false}
      ordinalColors={colors}
    />
    

    输出: enter image description here

    到这个d3.js v4示例

    <BarChart
      dimension={byYear}
      group={byYearGroup}
      x={d3.scaleTime()}
      renderHorizontalGridLines={true}
      elasticX={true}
      xUnits={d3.timeYears}
      ordinalColors={colors}
    />
    
    <AreaChart
      dimension={byYear}
      group={rockByYearGroup}
      x={d3.scaleTime()}
      renderHorizontalGridLines={true}
      elasticX={true}
      xUnits={d3.timeYears}
      renderArea={true}
      stack={[popByYearGroup, funkSoulByYearGroup, electroByYearGroup, hipHopByYearGroup]}
      xyTipsOn={true}
      brushOn={false}
      ordinalColors={colors}
    />
    

    输出: enter image description here

    这些是我在页面上的导入:

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import crossfilter from 'crossfilter'
    import {BarChart, AreaChart, PieChart, RowChart, ScatterPlot, SeriesChart} from './reactdc/react-dc'
    import './reactdc/react-dc.css'
    import albums from './data/albums'
    import * as d3 from 'd3';
    import dc from 'dc'
    

    此外,我已将coordinate-grid-mixin.js转换为v4标准:

    import React from 'react'
    import PropTypes from 'prop-types'
    import {compose, withProps} from '../utils'
    import colorMixin from './color-mixin'
    import marginMixin from './margin-mixin'
    import baseMixin from './base-mixin'
    
    const coordinateGridMixin = withProps({
      brushOn: PropTypes.bool,
      clipPadding: PropTypes.number,
      elasticX: PropTypes.bool,
      elasticY: PropTypes.bool,
      focus: PropTypes.arrayOf(PropTypes.number),
      mouseZoomable: PropTypes.bool,
      //rangeChart??????
      renderHorizontalGridLines: PropTypes.bool,
      renderVerticalGridLines: PropTypes.bool,
      round: PropTypes.func,
      useRightYAxis: PropTypes.bool,
      x: PropTypes.any.isRequired, // TO DO : PropTypes.any d3 quantitive scale or ordinal scale
      xAxis: {
        propTypes: PropTypes.shape({
          orient: PropTypes.string,
          ticks: PropTypes.array,
          tickValues: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string, Date])),
          tickSize: PropTypes.arrayOf(PropTypes.number),
          innerTickSize: PropTypes.number,
          outerTickSize: PropTypes.number,
          tickPadding: PropTypes.number,
          tickFormat: PropTypes.func
        }),
        setter(method, val){
          Object.entries(val).forEach(([key, value]) => method()[key](value))
        }
      },
      xAxisLabel: {
        propTypes: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
          labelText: PropTypes.string.isRequired,
          padding: PropTypes.number.isRequired
        })]),
        setter(method, val){
          if (val.labelText && val.padding){
            method(val.labelText, val.padding)
          }else{
            method(val)
          }
        }
      },
      xAxisPadding: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      xAxisUnit: PropTypes.string,
      y: PropTypes.any, // TO DO : d3 scale
      xUnits: PropTypes.func,
      yAxis: {
        propTypes: PropTypes.shape({
          orient: PropTypes.string,
          ticks: PropTypes.array,
          tickValues: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string, Date])),
          tickSize: PropTypes.arrayOf(PropTypes.number),
          innerTickSize: PropTypes.number,
          outerTickSize: PropTypes.number,
          tickPadding: PropTypes.number,
          tickFormat: PropTypes.func
        }),
        setter(method, val){
          Object.entries(val).forEach(([key, value]) => method()[key](value))
        }
      },
      yAxisLabel:  {
        propTypes: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
          labelText: PropTypes.string.isRequired,
          padding: PropTypes.number.isRequired
        })]),
        setter(method, val){
          if (val.labelText && val.padding){
            method(val.labelText, val.padding)
          }else{
            method(val)
          }
        }
      },
      yAxisPadding: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
      zoomOutRestrict: PropTypes.bool,
      zoomScale: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.arrayOf(PropTypes.instanceOf(Date))])
    })
    
    export default compose(coordinateGridMixin, colorMixin, marginMixin, baseMixin)
    

    我不确定我错过了什么。网上的v4示例也不多。

    我的图书馆版本如果有帮助:

    {
      "dependencies": {
        "crossfilter": "^1.3.12",
        "d3": "^4.13.0",
        "d3-scale": "^2.0.0",
        "d3-shape": "^1.2.0",
        "dc": "^2.1.9",
        "prop-types": "^15.6.0",
        "react": "^16.2.0",
        "react-dom": "^16.2.0",
        "react-scripts": "1.1.0",
        "recompose": "^0.26.0"
      }
    

    更新#1 我做了一些挖掘,发现dc.js文件中的以下代码行没有返回任何内容。

    var units = _chart.xUnits()(_chart.x().domain()[0], _chart.x().domain()[1], _chart.x().domain());
    

    当我进入这一行时,它会调用一个范围函数(来自较新的d3.js(v.4.13.0) - &gt; interval.js文件的修改版本),该函数被移动到interval.js文件并且期望step值作为最后一个参数。

    interval.range = function(start, stop, step) {
        var range = [], previous;
        start = interval.ceil(start);
        step = step == null ? 1 : Math.floor(step);
        if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
        do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
        while (previous < start && start < stop);
        return range;
      };
    

    与此旧版本相比,因为最后一个参数接受数组

    function range(t0, t1, dt) {
          var time = ceil(t0), times = [];
          if (dt > 1) {
            while (time < t1) {
              if (!(number(time) % dt)) times.push(new Date(+time));
              step(time, 1);
            }
          } else {
            while (time < t1) times.push(new Date(+time)), step(time, 1);
          }
          return times;
        }
    

0 个答案:

没有答案