typescript - Gráfica de líneas básica usando D3.js v4 (NO v3)
Me está costando encontrar un ejemplo de un gráfico de líneas que no use fechas en D3.js v4, principalmente porque no estoy seguro de cómo crear el eje x usando d3.scaleOrdinal(), ya que obtengo este error (en TypeScript) cuando intento hacerlo:
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
Error:
El argumento de tipo 'ScaleOrdinal<string, {}>' no se puede asignar al parámetro de tipo 'AxisScale<string>'.
¿Algún ejemplo súper básico de cómo crear un gráfico de líneas con estos datos?
[{label: 'A', value: 3}, {label: 'B', value: 4}, {label: 'C', value: 2}]
Gracias.
Respuesta #1
Mira este sencillo ejemplo de gráfico de líneas con d3 versión 4.5 - http://codepen.io/marcobiedermann/pen/GWGJvM
Lo bifurqué y lo reorganicé para tus datos - 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}]);
