Close Editor Run Reset Auto Update CJS /*
* LightningChartJS example that showcases stacked mountains chart.
*/
// Import LightningChartJS
const lcjs = require('@lightningchart/lcjs')
// Extract required parts from LightningChartJS.
const { lightningChart, AxisTickStrategies, emptyFill, Themes } = lcjs
// Create a XY Chart.
const xyChart = lightningChart().ChartXY({
legend: { visible: false },
// theme: Themes.darkGold
})
xyChart
.setTitle('Proportion of versions over time')
.setUserInteractions(undefined)
.setCursorFormatting((_, hit, hits) => {
console.log(hits)
return [
{ text: hit.axisX.formatValue(hit.x), rowFillStyle: xyChart.getTheme().cursorResultTableHeaderBackgroundFillStyle },
...hits.map((hit) => [hit.series, '', { text: `${Math.abs(hit.range1 - hit.range2).toFixed(1)}%` }]),
]
})
// Set up the X and Y Axes for the chart.
xyChart
.getDefaultAxisX()
.setTickStrategy(AxisTickStrategies.DateTime)
.setInterval({
start: new Date(2017, 0, 1).getTime(),
end: new Date(2018, 3, 1).getTime(),
})
xyChart.getDefaultAxisY().setTitle('Distribution').setUnits('%').setInterval({ start: 0, end: 100, stopAxisAfter: false })
// ---- Add multiple series with different names and values. ----
const versionName = [
'Version 1',
'Version 2',
'Version 3',
'Version 4',
'Version 5',
'Version 6',
'Version 7',
'Version 8',
'Version 9',
'Version 10',
'Version 11',
'Version 12',
]
// Array to store the created Area Series.
const version = []
// Create Series for each version name.
versionName.forEach((v, k) => {
version[k] = xyChart.addAreaRangeSeries().setName(v).setPointFillStyle(emptyFill)
})
// Create data for each Version.
const data = [
[
{ x: new Date(2017, 0, 1).getTime(), y: 1.3 },
{ x: new Date(2017, 1, 1).getTime(), y: 1.2 },
{ x: new Date(2017, 2, 1).getTime(), y: 1.1 },
{ x: new Date(2017, 3, 1).getTime(), y: 1.1 },
{ x: new Date(2017, 4, 1).getTime(), y: 1 },
{ x: new Date(2017, 5, 1).getTime(), y: 0.9 },
{ x: new Date(2017, 6, 1).getTime(), y: 0.8 },
{ x: new Date(2017, 7, 1).getTime(), y: 0.8 },
{ x: new Date(2017, 8, 1).getTime(), y: 0.7 },
{ x: new Date(2017, 9, 1).getTime(), y: 0.7 },
{ x: new Date(2017, 10, 1).getTime(), y: 0.6 },
{ x: new Date(2017, 11, 1).getTime(), y: 0.6 },
{ x: new Date(2018, 0, 1).getTime(), y: 0.5 },
{ x: new Date(2018, 1, 1).getTime(), y: 0.5 },
{ x: new Date(2018, 2, 1).getTime(), y: 0.5 },
{ x: new Date(2018, 3, 1).getTime(), y: 0.4 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 4.9 },
{ x: new Date(2017, 1, 1).getTime(), y: 4.5 },
{ x: new Date(2017, 2, 1).getTime(), y: 4.2 },
{ x: new Date(2017, 3, 1).getTime(), y: 4 },
{ x: new Date(2017, 4, 1).getTime(), y: 3.7 },
{ x: new Date(2017, 5, 1).getTime(), y: 3.5 },
{ x: new Date(2017, 6, 1).getTime(), y: 3.3 },
{ x: new Date(2017, 7, 1).getTime(), y: 3.1 },
{ x: new Date(2017, 8, 1).getTime(), y: 2.9 },
{ x: new Date(2017, 9, 1).getTime(), y: 2.7 },
{ x: new Date(2017, 10, 1).getTime(), y: 2.5 },
{ x: new Date(2017, 11, 1).getTime(), y: 2.3 },
{ x: new Date(2018, 0, 1).getTime(), y: 2.2 },
{ x: new Date(2018, 1, 1).getTime(), y: 2 },
{ x: new Date(2018, 2, 1).getTime(), y: 1.9 },
{ x: new Date(2018, 3, 1).getTime(), y: 1.7 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 6.8 },
{ x: new Date(2017, 1, 1).getTime(), y: 6.4 },
{ x: new Date(2017, 2, 1).getTime(), y: 5.9 },
{ x: new Date(2017, 3, 1).getTime(), y: 5.7 },
{ x: new Date(2017, 4, 1).getTime(), y: 5.4 },
{ x: new Date(2017, 5, 1).getTime(), y: 5.2 },
{ x: new Date(2017, 6, 1).getTime(), y: 4.8 },
{ x: new Date(2017, 7, 1).getTime(), y: 4.4 },
{ x: new Date(2017, 8, 1).getTime(), y: 4.1 },
{ x: new Date(2017, 9, 1).getTime(), y: 3.9 },
{ x: new Date(2017, 10, 1).getTime(), y: 3.5 },
{ x: new Date(2017, 11, 1).getTime(), y: 3.3 },
{ x: new Date(2018, 0, 1).getTime(), y: 3.1 },
{ x: new Date(2018, 1, 1).getTime(), y: 3 },
{ x: new Date(2018, 2, 1).getTime(), y: 2.9 },
{ x: new Date(2018, 3, 1).getTime(), y: 2.6 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 3 },
{ x: new Date(2017, 1, 1).getTime(), y: 2.2 },
{ x: new Date(2017, 2, 1).getTime(), y: 1.7 },
{ x: new Date(2017, 3, 1).getTime(), y: 1.6 },
{ x: new Date(2017, 4, 1).getTime(), y: 1.5 },
{ x: new Date(2017, 5, 1).getTime(), y: 1.5 },
{ x: new Date(2017, 6, 1).getTime(), y: 1.3 },
{ x: new Date(2017, 7, 1).getTime(), y: 1.3 },
{ x: new Date(2017, 8, 1).getTime(), y: 1.2 },
{ x: new Date(2017, 9, 1).getTime(), y: 1.1 },
{ x: new Date(2017, 10, 1).getTime(), y: 1 },
{ x: new Date(2017, 11, 1).getTime(), y: 1 },
{ x: new Date(2018, 0, 1).getTime(), y: 0.9 },
{ x: new Date(2018, 1, 1).getTime(), y: 0.9 },
{ x: new Date(2018, 2, 1).getTime(), y: 0.8 },
{ x: new Date(2018, 3, 1).getTime(), y: 0.7 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 25.2 },
{ x: new Date(2017, 1, 1).getTime(), y: 24.5 },
{ x: new Date(2017, 2, 1).getTime(), y: 23.5 },
{ x: new Date(2017, 3, 1).getTime(), y: 21.9 },
{ x: new Date(2017, 4, 1).getTime(), y: 20.8 },
{ x: new Date(2017, 5, 1).getTime(), y: 20.5 },
{ x: new Date(2017, 6, 1).getTime(), y: 19.5 },
{ x: new Date(2017, 7, 1).getTime(), y: 18.6 },
{ x: new Date(2017, 8, 1).getTime(), y: 17.6 },
{ x: new Date(2017, 9, 1).getTime(), y: 16.5 },
{ x: new Date(2017, 10, 1).getTime(), y: 15.3 },
{ x: new Date(2017, 11, 1).getTime(), y: 14.7 },
{ x: new Date(2018, 0, 1).getTime(), y: 13.8 },
{ x: new Date(2018, 1, 1).getTime(), y: 13.4 },
{ x: new Date(2018, 2, 1).getTime(), y: 12.8 },
{ x: new Date(2018, 3, 1).getTime(), y: 11.7 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 11.3 },
{ x: new Date(2017, 1, 1).getTime(), y: 10.8 },
{ x: new Date(2017, 2, 1).getTime(), y: 10.1 },
{ x: new Date(2017, 3, 1).getTime(), y: 9.8 },
{ x: new Date(2017, 4, 1).getTime(), y: 9.4 },
{ x: new Date(2017, 5, 1).getTime(), y: 9.2 },
{ x: new Date(2017, 6, 1).getTime(), y: 8.7 },
{ x: new Date(2017, 7, 1).getTime(), y: 8.2 },
{ x: new Date(2017, 8, 1).getTime(), y: 7.8 },
{ x: new Date(2017, 9, 1).getTime(), y: 7.4 },
{ x: new Date(2017, 10, 1).getTime(), y: 7.1 },
{ x: new Date(2017, 11, 1).getTime(), y: 6.7 },
{ x: new Date(2018, 0, 1).getTime(), y: 6.4 },
{ x: new Date(2018, 1, 1).getTime(), y: 6.1 },
{ x: new Date(2018, 2, 1).getTime(), y: 5.7 },
{ x: new Date(2018, 3, 1).getTime(), y: 5.4 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 22.8 },
{ x: new Date(2017, 1, 1).getTime(), y: 23.2 },
{ x: new Date(2017, 2, 1).getTime(), y: 23.3 },
{ x: new Date(2017, 3, 1).getTime(), y: 23.2 },
{ x: new Date(2017, 4, 1).getTime(), y: 23.1 },
{ x: new Date(2017, 5, 1).getTime(), y: 23 },
{ x: new Date(2017, 6, 1).getTime(), y: 23.3 },
{ x: new Date(2017, 7, 1).getTime(), y: 22.6 },
{ x: new Date(2017, 8, 1).getTime(), y: 22.3 },
{ x: new Date(2017, 9, 1).getTime(), y: 21.8 },
{ x: new Date(2017, 10, 1).getTime(), y: 21.7 },
{ x: new Date(2017, 11, 1).getTime(), y: 21.2 },
{ x: new Date(2018, 0, 1).getTime(), y: 20.8 },
{ x: new Date(2018, 1, 1).getTime(), y: 20.2 },
{ x: new Date(2018, 2, 1).getTime(), y: 19.8 },
{ x: new Date(2018, 3, 1).getTime(), y: 19.2 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 24 },
{ x: new Date(2017, 1, 1).getTime(), y: 26.8 },
{ x: new Date(2017, 2, 1).getTime(), y: 29.5 },
{ x: new Date(2017, 3, 1).getTime(), y: 30.7 },
{ x: new Date(2017, 4, 1).getTime(), y: 31.3 },
{ x: new Date(2017, 5, 1).getTime(), y: 31.2 },
{ x: new Date(2017, 6, 1).getTime(), y: 31.2 },
{ x: new Date(2017, 7, 1).getTime(), y: 31.2 },
{ x: new Date(2017, 8, 1).getTime(), y: 31.8 },
{ x: new Date(2017, 9, 1).getTime(), y: 32.3 },
{ x: new Date(2017, 10, 1).getTime(), y: 32.2 },
{ x: new Date(2017, 11, 1).getTime(), y: 32 },
{ x: new Date(2018, 0, 1).getTime(), y: 30.9 },
{ x: new Date(2018, 1, 1).getTime(), y: 29.7 },
{ x: new Date(2018, 2, 1).getTime(), y: 28.6 },
{ x: new Date(2018, 3, 1).getTime(), y: 28.8 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 0.7 },
{ x: new Date(2017, 1, 1).getTime(), y: 0.4 },
{ x: new Date(2017, 2, 1).getTime(), y: 0.5 },
{ x: new Date(2017, 3, 1).getTime(), y: 1.7 },
{ x: new Date(2017, 4, 1).getTime(), y: 3.4 },
{ x: new Date(2017, 5, 1).getTime(), y: 4.6 },
{ x: new Date(2017, 6, 1).getTime(), y: 6.6 },
{ x: new Date(2017, 7, 1).getTime(), y: 9.1 },
{ x: new Date(2017, 8, 1).getTime(), y: 10.6 },
{ x: new Date(2017, 9, 1).getTime(), y: 12.3 },
{ x: new Date(2017, 10, 1).getTime(), y: 14.4 },
{ x: new Date(2017, 11, 1).getTime(), y: 16 },
{ x: new Date(2018, 0, 1).getTime(), y: 17.8 },
{ x: new Date(2018, 1, 1).getTime(), y: 19.3 },
{ x: new Date(2018, 2, 1).getTime(), y: 21.1 },
{ x: new Date(2018, 3, 1).getTime(), y: 22.3 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 0 },
{ x: new Date(2017, 1, 1).getTime(), y: 0 },
{ x: new Date(2017, 2, 1).getTime(), y: 0.2 },
{ x: new Date(2017, 3, 1).getTime(), y: 0.3 },
{ x: new Date(2017, 4, 1).getTime(), y: 0.4 },
{ x: new Date(2017, 5, 1).getTime(), y: 0.4 },
{ x: new Date(2017, 6, 1).getTime(), y: 0.5 },
{ x: new Date(2017, 7, 1).getTime(), y: 0.7 },
{ x: new Date(2017, 8, 1).getTime(), y: 1 },
{ x: new Date(2017, 9, 1).getTime(), y: 1.3 },
{ x: new Date(2017, 10, 1).getTime(), y: 1.7 },
{ x: new Date(2017, 11, 1).getTime(), y: 2 },
{ x: new Date(2018, 0, 1).getTime(), y: 3.3 },
{ x: new Date(2018, 1, 1).getTime(), y: 4.4 },
{ x: new Date(2018, 2, 1).getTime(), y: 5.2 },
{ x: new Date(2018, 3, 1).getTime(), y: 6.1 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 0 },
{ x: new Date(2017, 1, 1).getTime(), y: 0 },
{ x: new Date(2017, 2, 1).getTime(), y: 0 },
{ x: new Date(2017, 3, 1).getTime(), y: 0 },
{ x: new Date(2017, 4, 1).getTime(), y: 0 },
{ x: new Date(2017, 5, 1).getTime(), y: 0 },
{ x: new Date(2017, 6, 1).getTime(), y: 0 },
{ x: new Date(2017, 7, 1).getTime(), y: 0 },
{ x: new Date(2017, 8, 1).getTime(), y: 0 },
{ x: new Date(2017, 9, 1).getTime(), y: 0 },
{ x: new Date(2017, 10, 1).getTime(), y: 0 },
{ x: new Date(2017, 11, 1).getTime(), y: 0.2 },
{ x: new Date(2018, 0, 1).getTime(), y: 0.3 },
{ x: new Date(2018, 1, 1).getTime(), y: 0.5 },
{ x: new Date(2018, 2, 1).getTime(), y: 0.5 },
{ x: new Date(2018, 3, 1).getTime(), y: 0.8 },
],
[
{ x: new Date(2017, 0, 1).getTime(), y: 0 },
{ x: new Date(2017, 1, 1).getTime(), y: 0 },
{ x: new Date(2017, 2, 1).getTime(), y: 0 },
{ x: new Date(2017, 3, 1).getTime(), y: 0 },
{ x: new Date(2017, 4, 1).getTime(), y: 0 },
{ x: new Date(2017, 5, 1).getTime(), y: 0 },
{ x: new Date(2017, 6, 1).getTime(), y: 0 },
{ x: new Date(2017, 7, 1).getTime(), y: 0 },
{ x: new Date(2017, 8, 1).getTime(), y: 0 },
{ x: new Date(2017, 9, 1).getTime(), y: 0 },
{ x: new Date(2017, 10, 1).getTime(), y: 0 },
{ x: new Date(2017, 11, 1).getTime(), y: 0 },
{ x: new Date(2018, 0, 1).getTime(), y: 0 },
{ x: new Date(2018, 1, 1).getTime(), y: 0 },
{ x: new Date(2018, 2, 1).getTime(), y: 0.2 },
{ x: new Date(2018, 3, 1).getTime(), y: 0.3 },
],
]
// Function to get the proper High value for a Series.
const getYHigh = (p, k) => {
let sum = 0
while (p >= 0) {
sum += data[p][k].y
p--
}
return sum
}
// Function to get the proper Low value for a Series.
const getYLow = (p, k) => {
let sum = 0
while (p - 1 >= 0) {
sum += data[p - 1][k].y
p--
}
return sum
}
/**
* Fill each Area Series with the data created for them.
*/
data[0].forEach((point, i) => {
version.forEach((series, index) => {
version[index].appendSample({
position: point.x,
high: getYHigh(index, i),
low: getYLow(index, i),
})
})
})
JavaScript Stacked Mountains Chart - Editor Also known as Stacked Area Graph or Stacked Areas
The stacked charts are a popular visual aid used for categorizing and comparing the parts of a whole using different colors to distinguish the categories.
This chart is created with custom stacking logic by using AreaRange series and position each next data segment on top of the previous. Relying on characteristics and use cases of mountain series mentioned in previous examples, area is drawn on a Cartesian coordinate system and represents the quantitative data. Thus, in the example, the first data segment starts from a zero baseline and each next category would use the magnitude of previous segment as a low starting point.
const areaNext1 = chart. addAreaRangeSeries ( )
const areaNext2 = chart. addAreaRangeSeries ( )