我是所有D3 /反应编码的新手。我正在将D3 v3示例转换为D3 v4(React-DC)。我能够转换饼图和行图。但我被困在条形图和区域图表中。这似乎是一个小问题,因为我可以看到渲染的图表,但有以下问题(对于冗长的内容提前抱歉):
条形图:条形宽度为1像素。我查了DC js FAQ page in github,他们说我必须设置xUnits。但是,我已经定义了xUnits,但它仍然无法工作。
面积图(已堆叠):仅显示一个?我没有看到剩下的筹码。
我转换了这个有效的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}
/>
到这个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}
/>
这些是我在页面上的导入:
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;
}