Close Editor Run Reset Auto Update CJS const lcjs = require('@lightningchart/lcjs')
const { lightningChart, AxisTickStrategies, emptyFill, AutoCursorModes, IndividualPointFill, Themes } = lcjs
const lc = lightningChart()
const chart = lc
.ChartXY({
legend: { visible: false },
defaultAxisX: { type: 'linear-highPrecision' },
// theme: Themes.darkGold
})
.setTitle('Custom data selection interaction (drag with left mouse above chart)')
const axisX = chart.getDefaultAxisX().setTickStrategy(AxisTickStrategies.DateTime).setAnimationScroll(false)
// Disable conflicting built-in interactions
chart.setUserInteractions({ rectangleZoom: false })
// Generate random data for example
const data = []
let yPrev = 100
for (let i = 0; i < 1000; i += 1) {
const x = Date.UTC(2023, 0, i)
const y = yPrev + (Math.random() * 2 - 1)
yPrev = y
data.push({ x, y })
}
const lineSeries = chart.addLineSeries()
const colorNormal = lineSeries.getStrokeStyle().getFillStyle().getColor()
const colorUnselected = chart.getTheme().examples.unfocusedDataColor
const colorSelected = chart.getTheme().examples.positiveFillStyle.getColor()
lineSeries
.setPointerEvents(false)
.setStrokeStyle((stroke) => stroke.setFillStyle(new IndividualPointFill()))
.appendJSON(data, undefined, { color: colorNormal })
// Setup custom user interaction
const band = axisX.addBand(false).setVisible(false)
chart.seriesBackground.addEventListener('pointerdown', (event) => {
const locAxis = chart.translateCoordinate(event, chart.coordsAxis)
band.setVisible(true)
band.setValueStart(locAxis.x).setValueEnd(locAxis.x)
chart.setCursorMode(undefined)
const handleMove = (event) => {
const locAxis = chart.translateCoordinate(event, chart.coordsAxis)
band.setValueEnd(locAxis.x)
}
const handleUp = (event) => {
band.setVisible(false)
chart.setCursorMode('show-nearest')
// Highlight all data points inside band
const xMin = Math.min(band.getValueStart(), band.getValueEnd())
const xMax = Math.max(band.getValueStart(), band.getValueEnd())
// NOTE: In this example, could just as well use `data` variable directly. But showing use of `readback` for example purposes.
// Alternatively could directly pass x range to readBack onlyInRange parameter, but again, showing more flexible use of custom logic for example purposes.
const dataSet = lineSeries.readBack()
const alteredSampleIndexes = []
for (let i = 0; i < dataSet.xValues.length; i += 1) {
const x = dataSet.xValues[i]
if (x >= xMin && x <= xMax) alteredSampleIndexes.push(dataSet.iSampleFirst + i)
}
lineSeries.fill({ color: colorUnselected }).alterSamplesByIndex(alteredSampleIndexes, { color: colorSelected })
document.body.removeEventListener('pointermove', handleMove)
document.body.removeEventListener('pointerup', handleUp)
}
document.body.addEventListener('pointermove', handleMove)
document.body.addEventListener('pointerup', handleUp)
})
JavaScript Custom Time Selection Chart - Editor This example showcases the creation of a custom user interaction.
Any custom interaction can be implemented with different event subscription methods. In this example, ChartXY.addEventListener is used to hook on to the event when user drags with mouse inside the series area. An Axis band is used to highlight the selected time range, and after user stops dragging the Line series is colored so that selected points are focused whereas other points are "unfocused".
This idea of custom interactions can be extended to any application specific dynamic interaction, like deleting selected points, displaying them in a separate chart or moving them - imagination is the limit!
See also: