Skip to content

Instantly share code, notes, and snippets.

@ColinEberhardt
Last active May 28, 2019 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ColinEberhardt/0a5cc7ca6c256dcd6ef1e2e7ffa468d4 to your computer and use it in GitHub Desktop.
Save ColinEberhardt/0a5cc7ca6c256dcd6ef1e2e7ffa468d4 to your computer and use it in GitHub Desktop.
Discontinuous Axis - Removing Weekends
license: mit

This example demonstrates how to render a financial candlestick chart on a discontinuous scale that skips weekends. Try clicking the checkbox to observe the difference, when checked, the weekends, where no trading occurs, are removed from the chart.

With financial data, there are often regular 'breaks', exchanges typically only trade on weekdays, and during certain hours of the day. For that reason, the data is rendered on a chart where the scale has 'discontinuities', or in other words, sections that are removed.

This example demonstrates how the d3fc discontinuous scale can be used to adapt a d3 time scale adding in discontinuity provider that skips weekends.

const skipWeekendScale = fc.scaleDiscontinuous(d3.scaleTime())
  .discontinuityProvider(fc.discontinuitySkipWeekends());

You can create all kinds of interesting discontinuity providers, that skips certain hours of day, or just remove a certain section from the scale.

N.B. By default, the automatic tick positioning of the scale will try to place the ticks on Sunday's at midnight. Unfortunately this they will be filtered out by the discontinuous scale because the ticks fall within the discontinuities. To work around this you can manually specify the tick interval using d3-time

<!DOCTYPE html>
<!-- include polyfills for custom event, Symbol and Custom Elements -->
<script src="//unpkg.com/babel-polyfill@6.26.0/dist/polyfill.js"></script>
<script src="//unpkg.com/custom-event-polyfill@0.3.0/custom-event-polyfill.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/document-register-element/1.8.0/document-register-element.js"></script>
<!-- use babel so that we can use arrow functions and other goodness in this block! -->
<script src="//unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="//unpkg.com/d3@5.5.0"></script>
<script src="//unpkg.com/d3fc@14.0.41"></script>
<meta charset="utf-8">
<style>
body {
font: 18px sans-serif;
}
.chart {
height: 480px;
}
</style>
<label><input type='checkbox' id='skip'/>skip weekends</label>
<div id='streaming-chart' class='chart'></div>
<script type='text/babel'>
const DAY_MS = 1000 * 60 * 60 * 24;
const checkbox = document.getElementById('skip');
// create some test data that skips weekends
const generator = fc.randomFinancial()
.filter(fc.randomSkipWeekends);
const data = generator(50);
const xTickFilter = d3.timeDay.filter((d) => d.getDay() === 1);
// use the date to determine the x extent, padding by one day at each end
const xExtent = fc.extentDate()
.accessors([d => d.date])
.padUnit('domain')
.pad([DAY_MS, DAY_MS])
// compute the y extent from the high / low values, padding by 10%
const yExtent = fc.extentLinear()
.accessors([d => d.high, d => d.low])
.pad([0.1, 0.1])
// Create the gridlines and series
const gridlines = fc.annotationSvgGridline()
.xTicks(xTickFilter);
const candlestick = fc.seriesSvgCandlestick();
// add them to the chart via a multi-series
const multi = fc.seriesSvgMulti()
.series([gridlines, candlestick]);
// adapt the d3 time scale in a discontinuous scale that skips weekends
const skipWeekendScale = fc.scaleDiscontinuous(d3.scaleTime())
.discontinuityProvider(fc.discontinuitySkipWeekends());
function renderChart() {
// create a chart
const chart = fc.chartCartesian(
checkbox.checked ? skipWeekendScale : d3.scaleTime(),
d3.scaleLinear()
)
.xDomain(xExtent(data))
.yDomain(yExtent(data))
.xTicks(xTickFilter)
.svgPlotArea(multi);
// render the chart
d3.select('#streaming-chart')
.datum(data)
.call(chart);
}
renderChart();
checkbox.addEventListener('click', renderChart);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment