我正在使用 LightningChartJS v. 1.3.1 并且有一个包含多个系列的图表。
我想让光标在所有行上并同时在光标旁边显示一个标签。
据我所知,有一种方法可以将光标放在最近的系列上:
chart.setAutoCursorMode(AutoCursorModes.snapToClosest)
我没有找到一种方法来默认启用所有行的光标。
所以我使用mousemove事件侦听器来捕获事件并将光标放在所有行上。不幸的是,如果线条靠近或相互交叉,并且光标在线条上不精确,则标签重叠,因为我必须通过搜索源数据中最近的索引来找到 y 值。
如果有人能帮助我回答以下问题,我将不胜感激:
1、如何防止标签重叠并控制标签位置?
2. 有没有更优雅的方式在所有系列上显示光标?
如果无法控制y轴上的标签,
也许左右交替设置位置就足够了。
3. 怎么做?
请看下面的例子:
const {
AutoCursorModes, AxisTickStrategies, ChartMarkerXY, ChartXY, ColorHEX, ColorPalettes, ColorRGBA, DataPatterns, emptyFill, emptyLine, FontSettings, lightningChart, MarkerBuilders, PointShape, SolidFill, SolidLine, translatePoint, transparentFill, UIBackgrounds, UIDraggingModes, UIElement, UIElementBuilders, UILayoutBuilders, UIOrigins, UIVisibilityModes, VisibleTicks
} = lcjs
const setData = (count) => {
const data = [];
for (var i = 0; i < count; i++) {
data.push({x: i, y: Math.floor(Math.random() * 100) + 50});
}
return data;
}
const getIndexTimeStamp = (arr, x) => {
const goal = x;
let closestValue = Infinity;
let closestIndex = -1;
for (let i = 0; i < arr.length; ++i) {
const diff = Math.abs(arr[i].x - goal);
if (diff < closestValue) {
closestValue = diff;
closestIndex = i;
}
}
return closestIndex;
}
const setChartMarkerPosition = (marker, colorHex, locationX, yValue, content) => {
marker.setPosition({ x: locationX, y: yValue });
marker
.setResultTableVisibility(UIVisibilityModes.always)
.setResultTable((table) => table
.setContent([[content]])
.setTextFillStyle(new SolidFill({color: ColorHEX(colorHex)}))
.setBackground(background => background)
)
.setGridStrokeXVisibility(UIVisibilityModes.whenDragged)
.setGridStrokeYVisibility(UIVisibilityModes.whenDragged)
.setTickMarkerXVisibility(UIVisibilityModes.whenDragged)
.setTickMarkerYVisibility(UIVisibilityModes.whenDragged);
};
const chart = lightningChart().ChartXY({
containerId: "chart",
defaultAxisXTickStrategy: Object.assign({}, AxisTickStrategies.Numeric)
});
const axisY = chart.getDefaultAxisY();
axisY.setInterval(0, 200, false, true);
const series1 = chart.addLineSeries({ dataPattern: DataPatterns.horizontalProgressive}).setStrokeStyle(new SolidLine({thickness: 1.2, fillStyle: new SolidFill({color: ColorHEX('#FF0000')} )} ))
.setResultTableFormatter((tableBuilder, series, x, y) => tableBuilder
// is empty to skip marker text
);
const series2 = chart.addLineSeries({ dataPattern: DataPatterns.horizontalProgressive}).setStrokeStyle(new SolidLine({thickness: 1.2, fillStyle: new SolidFill({color: ColorHEX('#FFFF00')})}))
.setResultTableFormatter((tableBuilder, series, x, y) => tableBuilder
// is empty to skip marker text);
);
const series3 = chart.addLineSeries({ dataPattern: DataPatterns.horizontalProgressive}).setStrokeStyle(new SolidLine({thickness: 1.2, fillStyle: new SolidFill({color: ColorHEX('#FFFFFF')})}))
.setResultTableFormatter((tableBuilder, series, x, y) => tableBuilder
// is empty to skip marker text
);
const data1 = setData(100);
const data2 = setData(100);
const data3 = setData(100);
series1.add( data1 );
series2.add( data2 );
series3.add( data3 );
const elem = document.getElementById('chart');
const elemLeftSpace = elem.getBoundingClientRect().left;
const elemTopSpace = elem.getBoundingClientRect().top;
let marker1;
let marker2;
let marker3;
elem.addEventListener( 'mousemove', ( event ) => {
const cursorPoint = chart.solveNearest({x: event.clientX - elemLeftSpace, y: event.clientY - elemTopSpace});
if (cursorPoint) {
const locationOnAxes = translatePoint(
chart.engine.clientLocation2Engine(event.clientX, event.clientY),
chart.engine.scale,
{
x: chart.getDefaultAxisX().scale,
y: chart.getDefaultAxisY().scale
});
const foundSeries_1 = getIndexTimeStamp(data1, Math.ceil(cursorPoint.location.x));
const foundSeries_2 = getIndexTimeStamp(data2, Math.ceil(cursorPoint.location.x));
const foundSeries_3 = getIndexTimeStamp(data3, Math.ceil(cursorPoint.location.x));
if (foundSeries_1 > -1) {
if (!marker1) { marker1 = chart.addChartMarkerXY(); }
setChartMarkerPosition(
marker1,
'#FF0000',
cursorPoint.location.x,
data1[foundSeries_1].y,
'Marker 1: ' + (cursorPoint.location.y).toFixed(1)
);
}
if (foundSeries_2 > -1) {
if (!marker2) { marker2 = chart.addChartMarkerXY(); }
setChartMarkerPosition(
marker2,
'#FFFF00',
cursorPoint.location.x,
data2[foundSeries_2].y,
'Marker 2 ' + (cursorPoint.location.y).toFixed(3)
);
}
if (foundSeries_3 > -1) {
if (!marker3) { marker3 = chart.addChartMarkerXY(); }
setChartMarkerPosition(
marker3,
'#FFFFFF',
cursorPoint.location.x,
data3[foundSeries_3].y,
'Marker 3: ' + (cursorPoint.location.y).toFixed(1)
);
}
}
});
<div class="wrapper">
<div id="chart" style="height: 200px;"></div>
</div>
<script src="https://unpkg.com/@arction/lcjs@1.3.1/dist/lcjs.iife.js"></script>