|
// adapt the d3 time scale to add discontinuities, so that weekends are removed |
|
const xScale = fc.scaleDiscontinuous(d3.scaleTime()) |
|
.discontinuityProvider(fc.discontinuitySkipWeekends()); |
|
|
|
const priceScale = d3.scaleLinear(); |
|
const volumeScale = d3.scaleLinear(); |
|
|
|
// a candlestick series, by default it expects the provided data to have open, low, high, close, date properties |
|
const candlestickSeries = fc.autoBandwidth(fc.seriesSvgOhlc()) |
|
.xScale(xScale) |
|
.yScale(priceScale); |
|
|
|
const volumeSeries = fc.autoBandwidth(fc.seriesSvgBar()) |
|
.mainValue(d => d.volume) |
|
.crossValue(d => d.date) |
|
.xScale(xScale) |
|
.yScale(volumeScale); |
|
|
|
const xAxis = d3.axisBottom() |
|
.scale(xScale); |
|
const priceAxis = d3.axisLeft() |
|
.scale(priceScale); |
|
const volumeAxis = d3.axisRight() |
|
.scale(volumeScale) |
|
.ticks(3) |
|
.tickFormat(d3.format(',.3s')); |
|
|
|
// use the extent component to determine the x and y domain |
|
const xExtent = fc.extentDate() |
|
.accessors([d => d.date]); |
|
|
|
const yExtent = fc.extentLinear() |
|
.accessors([d => d.high, d => d.low]) |
|
.pad([0.1, 0.1]); |
|
|
|
const volumeExtent = fc.extentLinear() |
|
.accessors([d => d.volume]) |
|
.include([0]) |
|
|
|
const parseDate = d3.timeParse("%d-%b-%y"); |
|
|
|
// handle the plot area measure event in order to determine the axis range |
|
d3.select('#plot-area') |
|
.on('measure', () => { |
|
const { width, height } = event.detail; |
|
xScale.range([0, width]); |
|
priceScale.range([height, 0]); |
|
volumeScale.range([height, height * 2 / 3]); |
|
}); |
|
|
|
// handle the x-axis draw event, rendering the axis |
|
d3.select('#x-axis') |
|
.on('draw', (d, i, nodes) => { |
|
d3.select(nodes[i]) |
|
.select('svg') |
|
.call(xAxis); |
|
}); |
|
|
|
// handle the y-axis measure event in order to offset the SVG to the left, and the |
|
// draw event for rendering |
|
d3.select('#y-axis') |
|
.on('measure', (d, i, nodes) => { |
|
const { width, height } = event.detail; |
|
d3.select(nodes[i]) |
|
.select('svg') |
|
.attr('viewBox', `${-width} 0 ${width} ${height}`); |
|
}) |
|
.on('draw', (d, i, nodes) => { |
|
const sel = d3.select(nodes[i]) |
|
.select('svg') |
|
.selectAll('g') |
|
.data([0]) |
|
.enter(); |
|
sel.append('g') |
|
.call(priceAxis); |
|
sel.append('g') |
|
.call(volumeAxis); |
|
}); |
|
|
|
d3.csv('data.csv', |
|
// transform the data to use the default candlestick series properties |
|
row => ({ |
|
open: Number(row.Open), |
|
close: Number(row.Close), |
|
high: Number(row.High), |
|
low: Number(row.Low), |
|
volume: Number(row.Volume), |
|
date: parseDate(row.Date) |
|
})).then(data => { |
|
|
|
// handle the plot area draw event, supplying the data and rendering the seroes |
|
d3.select('#plot-area') |
|
.on('draw', (d, i, nodes) => { |
|
const sel = d3.select(nodes[i]) |
|
.select('svg') |
|
.selectAll('g') |
|
.data([data]) |
|
.enter(); |
|
sel.append('g') |
|
.classed('volume', true) |
|
.call(volumeSeries); |
|
sel.append('g') |
|
.call(candlestickSeries); |
|
}); |
|
|
|
xScale.domain(xExtent(data)); |
|
priceScale.domain(yExtent(data)); |
|
volumeScale.domain(volumeExtent(data)); |
|
|
|
d3.select('#chart') |
|
.node() |
|
.requestRedraw(); |
|
}); |
HI~
I reference to this article:(https://bl.ocks.org/ColinEberhardt/485ad09b7967e2a0f9bfe6e10192c26a)
I have follow the (chart,js) source code~ but why the chart is not responsive??