Histogram
The best approach to displaying Histograms with LightningChart JS is by using ChartXY and RectangleSeries.
Online example of this can be seen in this example.
const chart = lightningChart()
.ChartXY()
.setTitle('Histogram chart')
.setUserInteractions({
rectangleZoom: {
y: false,
},
zoom: {
y: false,
},
})
chart.axisX.setTitle('Age')
chart.axisY.setTitle('Count')
chart.axisX.setTickStrategy(AxisTickStrategies.Numeric, (strategy) =>
strategy.setCursorFormatter((x) => {
const bin = bins.find((bin) => x >= bin.binStart && x <= bin.binEnd)
if (!bin) return ''
return `[${FormattingFunctions.Numeric(bin.binStart, chart.axisX.getInterval())}, ${FormattingFunctions.Numeric(bin.binEnd, chart.axisX.getInterval())}]`
}),
)
const barFillStyle = new SolidFill({ color: ColorRGBA(255, 215, 0) })
const barStrokeStyle = new SolidLine({ thickness: 1, fillStyle: new SolidFill({ color: ColorRGBA(16, 16, 16) }) })
const rectSeries = chart
.addRectangleSeries()
.setName('Histogram series')
.setDefaultStyle((figure) => figure.setFillStyle(barFillStyle).setStrokeStyle(barStrokeStyle))
bins.forEach((bin) => {
const rectFigure = rectSeries.add({
x1: bin.binStart,
x2: bin.binEnd,
y1: 0,
y2: bin.values.length,
})
})
rectSeries.setCursorBehavior({
location: (info) => ({ x: (info.x1 + info.x2) / 2, y: info.y2 }),
})
Result is an interactive histogram chart with cursor and zooming functionality:


In above snippet, bins data structure originates from below pre-calculation applied to a flat number array:
// Calculation from number[] to `bins` data structure
const calculateHistogramBins = (data: number[], numberOfBins: number) => {
const minValue = Math.min(...data)
const maxValue = Math.max(...data)
const binSize = (maxValue - minValue) / numberOfBins
const bins: { binStart: number, binEnd: number, values: number[] }[] = []
for (let i = 0; i < numberOfBins; i++) {
const binStart = minValue + i * binSize
const binEnd = minValue + (i + 1) * binSize
bins.push({
binStart: Math.round(binStart * 100) / 100,
binEnd: Math.round(binEnd * 100) / 100,
values: [],
})
}
bins[numberOfBins - 1].binEnd = maxValue
data.forEach((value) => {
const binIndex = Math.floor((value - minValue) / binSize)
if (binIndex >= 0 && binIndex < numberOfBins) {
bins[binIndex].values.push(value)
}
})
return bins
}