我有处理图表中线条的逻辑,并有一个从这个链接获得的自定义光标,当我处理线条时,标签不应该也显示出来,它可以工作,但在恢复rowY后,文本框中的名称是苍白的,在处理之前查看下一个屏幕截图苍白标签图像,正常标签
rowsY.map((rowY, i) => {
this.seriesInstances[i][1].isDisposed() ? rowY.dispose() : rowY.restore();
if (nearestDataPoints[i]?.location?.y) {
rowY.setText(`${this.seriesInstances[i][1].getName()}: ${+this.chartInstance.getDefaultAxisY().formatValue(nearestDataPoints[i].location.y)} ${this.seriesInitialData[i].unit}`)
}
});
您似乎在onSeriesBackgroundMouseMove中处理/恢复了rowY。我建议在处理/恢复系列实例的地方这样做,但它仍然无法使用图例框。要修复它,你可以只处理RowsY和RowX而不是resultTable,并在检查后恢复它:
rowX.restore()
series.forEach((el, i)=>{
//check if series was disposed
if(!el.isDisposed()){
rowsY[i].restore()
}
})
此外,在v.4.0中,我们将添加新的API,以取代处置/恢复
以下是使用的示例中的更新代码
// Import LightningChartJS
const lcjs = require("@arction/lcjs");
// Import data-generators from 'xydata'-library.
const { createProgressiveTraceGenerator } = require("@arction/xydata");
// Extract required parts from LightningChartJS.
const {
lightningChart,
AutoCursorModes,
UIElementBuilders,
UILayoutBuilders,
UIOrigins,
translatePoint,
Themes,
} = lcjs;
// Create a XY Chart.
const chart = lightningChart()
.ChartXY({
theme: Themes.lightNew,
})
// Disable native AutoCursor to create custom
.setAutoCursorMode(AutoCursorModes.disabled)
.setTitle('Custom Cursor using LCJS UI')
// set title for Y axis
chart.getDefaultAxisY().setTitle('Y-axis')
// generate data and creating the series
const series = new Array(3).fill(0).map((_, iSeries) => {
const nSeries = chart.addLineSeries({
dataPattern: {
// pattern: 'ProgressiveX' => Each consecutive data point has increased X coordinate.
pattern: 'ProgressiveX',
},
})
createProgressiveTraceGenerator()
.setNumberOfPoints(200)
.generate()
.toPromise()
.then((data) => {
return nSeries.add(data)
})
return nSeries
})
// Add Legend.
const legend = chart.addLegendBox().add(chart)
// Create UI elements for custom cursor.
const resultTable = chart
.addUIElement(UILayoutBuilders.Column, {
x: chart.getDefaultAxisX(),
y: chart.getDefaultAxisY(),
})
.setMouseInteractions(false)
.setOrigin(UIOrigins.LeftBottom)
.setMargin(5)
.setBackground((background) =>
background
// Style same as Theme result table.
.setFillStyle(chart.getTheme().resultTableFillStyle)
.setStrokeStyle(chart.getTheme().resultTableStrokeStyle),
)
const rowX = resultTable.addElement(UILayoutBuilders.Row).addElement(UIElementBuilders.TextBox)
const rowsY = series.map((el, i) => {
return resultTable
.addElement(UILayoutBuilders.Row)
.addElement(UIElementBuilders.TextBox)
.setTextFillStyle(series[i].getStrokeStyle().getFillStyle())
})
const tickX = chart.getDefaultAxisX().addCustomTick().setAllocatesAxisSpace(false)
const ticksY = series.map((el, i) => {
return chart
.getDefaultAxisY()
.addCustomTick()
.setAllocatesAxisSpace(false)
.setMarker((marker) => marker.setTextFillStyle(series[i].getStrokeStyle().getFillStyle()))
})
// Hide custom cursor components initially.
// resultTable.dispose()
rowsY.forEach(el=>{
el.dispose()
})
tickX.dispose()
ticksY.forEach((tick) => tick.dispose())
// Implement custom cursor logic with events.
chart.onSeriesBackgroundMouseMove((_, event) => {
const mouseLocationClient = { x: event.clientX, y: event.clientY }
// Translate mouse location to LCJS coordinate system for solving data points from series, and translating to Axes.
const mouseLocationEngine = chart.engine.clientLocation2Engine(mouseLocationClient.x, mouseLocationClient.y)
// Translate mouse location to Axis.
const mouseLocationAxis = translatePoint(mouseLocationEngine, chart.engine.scale, series[0].scale)
// Solve nearest data point to the mouse on each series.
const nearestDataPoints = series.map((el) => el.solveNearestFromScreen(mouseLocationEngine))
// Find the nearest solved data point to the mouse.
const nearestPoint = nearestDataPoints.reduce((prev, curr, i) => {
if (!prev) return curr
if (!curr) return prev
return Math.abs(mouseLocationAxis.y - curr.location.y) < Math.abs(mouseLocationAxis.y - prev.location.y) ? curr : prev
})
if (nearestPoint) {
// Set custom cursor location.
resultTable.setPosition({
x: nearestPoint.location.x,
y: nearestPoint.location.y,
})
// Change origin of result table based on cursor location.
if (nearestPoint.location.x > chart.getDefaultAxisX().getInterval().end / 1.5) {
if (nearestPoint.location.y > chart.getDefaultAxisY().getInterval().end / 1.5) {
resultTable.setOrigin(UIOrigins.RightTop)
} else {
resultTable.setOrigin(UIOrigins.RightBottom)
}
} else if (nearestPoint.location.y > chart.getDefaultAxisY().getInterval().end / 1.5) {
resultTable.setOrigin(UIOrigins.LeftTop)
} else {
resultTable.setOrigin(UIOrigins.LeftBottom)
}
// Format result table text.
rowX.setText(`X: ${chart.getDefaultAxisX().formatValue(nearestPoint.location.x)}`)
rowsY.forEach((rowY, i) => {
rowY.setText(`Y${i}: ${chart.getDefaultAxisY().formatValue(nearestDataPoints[i]?.location.y || 0)}`)
})
// Position custom ticks.
tickX.setValue(nearestPoint.location.x)
ticksY.forEach((tick, i) => {
tick.setValue(nearestDataPoints[i]?.location.y || 0)
})
// Display cursor.
rowX.restore()
series.forEach((el, i)=>{
if(!el.isDisposed()){
rowsY[i].restore()
}
})
tickX.restore()
ticksY.map((el) => el.restore())
} else {
// Hide cursor.
disposeCustomCursor()
tickX.dispose()
ticksY.map((el) => el.dispose())
}
})
chart.onSeriesBackgroundMouseLeave((_, e) => {
disposeCustomCursor()
tickX.dispose()
ticksY.map((el) => el.dispose())
})
chart.onSeriesBackgroundMouseDragStart((_, e) => {
disposeCustomCursor()
tickX.dispose()
ticksY.map((el) => el.dispose())
})
function disposeCustomCursor() {
rowX.dispose()
rowsY.forEach(el=>{
el.dispose()
})
}
setTimeout(() => {
series[0].dispose()
rowsY[0].dispose()
}, 3000);
setTimeout(() => {
series[0].restore()
rowsY[0].restore()
}, 6000);