Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map event position to y axis value in chartjs line chart

I am currently modifying a Chart.js line chart to be interactive. The idea is that the user can move the points of the graph with its fingers.

Here is an example how it looks like with the current mapping:

chart-test.html

I already managed it to read the events and get the data points which I have to modify:

// register pointer event
canvas.addEventListener('pointerdown', evt => {
    const points = interactiveChart.getElementsAtEventForMode(evt, 'index', {
        intersect: false
    });

    moveDataSetPoint(points, evt);
});

// change point relatively to y point
function moveDataSetPoint(points, evt)
{
    // read active data point
    var activePoint = points[0];
    var data = activePoint._chart.data;
    var datasetIndex = activePoint._datasetIndex;

    // read mouse position
    const helpers = Chart.helpers;
    var position = helpers.getRelativePosition(evt, interactiveChart);

    // calculate y axis value (ugly)
    // todo: map this with a chartjs method to map mouse inputs to yAxis values
    var yValue = map(position.y, window.myLine.height, 0, yMin, yMax);

    data.datasets[datasetIndex].data[activePoint._index] = yValue;
    window.myLine.update();
};

// attached the map function
function map(value, start1, stop1, start2, stop2) {
    return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1))
};

But the problem is that my map function is just mapping the y pointer position relatively to the canvas size and then y-axis min and max values.

This is very inaccurate and I am looking for a method which gives me the correct y-axis value from the pointer event values.

Is there something already implemented in chartjs? Or is there a method to get just the size of the chart itself, without the legends and borders around it (currently I am mapping to the whole canvas)?

like image 793
cansik Avatar asked Oct 17 '22 00:10

cansik


1 Answers

I found the solution for it by myself. You have to use the chart bottom and top properties to map the correct size:

// read chart area
var chartArea = chart.chartArea;
var yValue = map(position.y, chartArea.bottom, chartArea.top, yMin, yMax);

Then the mapping is pixel perfect.

like image 149
cansik Avatar answered Oct 21 '22 05:10

cansik