My task is to generate a line chart where the y-axis domain ranges from 1.01 to 1000. The tick values change at the following intervals along the axis:
- 1.01 to 2, tick = 0.01
- 2 to 3, tick = 0.02
- 3 to 4, tick = 0.05
- 4 to 6, tick = 0.1
- 6 to 10, tick = 0.2
- 10 to 20, tick = 0.5
- 20 to 30, tick = 1
- 30 to 50, tick = 2
- 50 to 100, tick = 5
- 100 to 1000, tick = 10
In the chart image, all the paths above x = 4.0 are twice as long as they should be. I have been exploring non-linear scales but haven't found a viable solution yet.
const svg = d3.select('#line_chart_svg');
const width = +svg.attr('width');
const height = +svg.attr('height');
const margin = { top: 20, bottom: 30, right: 20, left: 50 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const render = priceTimeData => {
const xValue = d => d.timeStamp;
const yValue = d => d.price;
const xScale = d3.scaleTime()
.domain(d3.extent(priceTimeData, xValue))
.range([0, innerWidth])
.nice();
const yScale = d3.scaleLinear()
.domain(d3.extent(priceTimeData, yValue))
.range([innerHeight, 0]);
console.log(yScale)
// Declare g and adjust size
const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// Setup xAxis
const xAxis = d3.axisBottom(xScale);
const xAxisG = g.append('g').call(xAxis)
.attr('transform', `translate(0, ${innerHeight})`);
// Setup yAxis
const yAxis = d3.axisLeft(yScale)
.tickSize(-innerWidth);
const yAxisG = g.append('g').call(yAxis);
const lineGenerator = d3.line()
.x(d => xScale(xValue(d)))
.y(d => yScale(yValue(d)));
g.append('path')
.attr('class', 'line_path')
.attr('d', lineGenerator(priceTimeData));
}
const priceTimeData = d3.csv('data/priceTime.csv').then(data => {
data.forEach(d => {
d.price = +d.price
d.timeStamp = new Date(d.timeStamp);
})
render(data)
});