我很难找到一个没有在 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}]
感谢。
答案 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}]);