Close Editor Run Reset Auto Update CJS const lcjs = require('@lightningchart/lcjs')
const {
lightningChart,
builtInDataDerivations,
AxisTickStrategies,
DataSet,
emptyFill,
emptyLine,
SolidLine,
SolidFill,
DashedLine,
StipplePatterns,
ColorRGBA,
Themes,
} = lcjs
const lc = lightningChart()
const chart = lc.ChartXY({
defaultAxisX: { type: 'linear-highPrecision' },
// theme: Themes.darkGold
})
.setTitle('Predicted vs. Actual Capacity')
chart.axisX.setTickStrategy(AxisTickStrategies.DateTime)
chart.axisY.setTitle('Requests per Day')
const theme = chart.getTheme()
const isDarkTheme = theme.isDark
// Helper function to calculate a target percentile (p) from a series of sorted arrays
const calculateValues = (rawValues, count, p) => {
const newValues = new Float64Array(count)
for (let i = 0; i < rawValues.length; i += 1) {
const values = rawValues[i]
const index = (values.length - 1) * p
const lower = Math.floor(index)
const upper = Math.ceil(index)
if (lower === upper) newValues[i] = values[lower]
const weight = index - lower
newValues[i] = values[lower] * (1 - weight) + values[upper] * weight
}
return newValues
}
const dataSet = new DataSet({
schema: {
timestamp: { pattern: 'progressive' },
actual: { pattern: 'progressive' },
median: {
pattern: null,
derived: (state) => {
const rawValuesNew = state.newValues['predictions']
const newValues = calculateValues(rawValuesNew, state.newCount, 0.50)
return newValues
},
},
p25: {
pattern: null,
derived: (state) => {
const rawValuesNew = state.newValues['predictions']
const newValues = calculateValues(rawValuesNew, state.newCount, 0.25)
return newValues
},
},
p75: {
pattern: null,
derived: (state) => {
const rawValuesNew = state.newValues['predictions']
const newValues = calculateValues(rawValuesNew, state.newCount, 0.75)
return newValues
},
},
sma: { pattern: null, derived: builtInDataDerivations.SMA({ source: 'actual', window: 7 }) }
},
})
chart
.addAreaRangeSeries()
.setName('Prediction Interval')
.setDataSet(dataSet, { position: 'timestamp', range1: 'p25', range2: 'p75' })
.setPointFillStyle(emptyFill, { range1: true, range2: true })
.setStrokeStyle(emptyLine, { range1: true, range2: true })
.setAreaFillStyle(new SolidFill({ color: isDarkTheme ? ColorRGBA(245, 140, 39, 50) : ColorRGBA(245, 160, 39, 80) }))
chart
.addLineSeries()
.setName('Forecast Median')
.setDataSet(dataSet, { x: 'timestamp', y: 'median' })
.setStrokeStyle(new DashedLine({
pattern: StipplePatterns.Dashed,
fillStyle: new SolidFill({ color: isDarkTheme ? ColorRGBA(245, 160, 39) : ColorRGBA(245, 140, 39) })
}))
chart
.addLineSeries()
.setName('Actual Capacity')
.setDataSet(dataSet, { x: 'timestamp', y: 'actual' })
.setStrokeStyle(new SolidLine({
thickness: 3,
fillStyle: new SolidFill({ color: isDarkTheme ? ColorRGBA(180, 34, 164) : ColorRGBA(0, 159, 48) })
}))
chart
.addLineSeries()
.setName('7-Day Average')
.setDataSet(dataSet, { x: 'timestamp', y: 'sma' })
.setStrokeStyle(new SolidLine({
fillStyle: new SolidFill({ color: isDarkTheme ? ColorRGBA(131, 34, 181) : ColorRGBA(0, 161, 170) })
}))
fetch(new URL(document.head.baseURI).origin + new URL(document.head.baseURI).pathname + 'examples/assets/1720/dataset.json')
.then((r) => r.json())
.then((data) => {
dataSet.appendJSON(data)
}) Derived Data Properties - Editor This is an example of a chart that tracks daily system capacity by comparing expected request volumes against the actual number of requests processed.
LightningChart DataSet class supports defining custom derivation rules, meaning data values can be derived from other properties' values. In this example, the dataset contains the base 'actual' and 'predictions' values. The median, prediction interval and SMA values are derived from those properties.
With Simple Moving Average (SMA), you can use built-in derivation implementation. You only need to feed in data values for x and y -> sma is automatically calculated. You can also specify any custom callback to do this kind of calculations.
const dataSet = new DataSet ( {
schema: {
x: { pattern: 'progressive' } ,
y: { pattern: null } ,
sma: { pattern: null , derived: builtInDataDerivations. SMA ( { source: 'y' , window: 100 } ) } ,
example: {
pattern: null ,
derived : ( info ) => {
return new Array ( info. newCount) . fill ( 0 ) . map ( Math. random)
} ,
} ,
} ,
} )