Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getElementAtEvent rxjs issue #5103

Closed
Mek89 opened this issue Jan 3, 2018 · 7 comments
Closed

getElementAtEvent rxjs issue #5103

Mek89 opened this issue Jan 3, 2018 · 7 comments

Comments

@Mek89
Copy link

Mek89 commented Jan 3, 2018

Hi,

In firefox when I tried to call this function:
chart.getElementAtEvent(event)

got some error:
TypeError: canvas is undefined Stack trace: module.exports/helpers.getRelativePosition@webpack-internal:///../../../../chart.js/src/core/core.helpers.js:380:7 getRelativePosition@webpack-internal:///../../../../chart.js/src/core/core.interaction.js:19:9 single@webpack-internal:///../../../../chart.js/src/core/core.interaction.js:156:19 getElementAtEvent@webpack-internal:///../../../../chart.js/src/core/core.controller.js:629:11

The problem looks like this (core.helper.js):
helpers.getRelativePosition = function(evt, chart) { var mouseX, mouseY; var e = evt.originalEvent || evt; var canvas = evt.currentTarget || evt.srcElement;......

CurrentTarget already gone and in firefox srcElement does not exist. Maybe should use 'target' instead?
Any idea how can I make some quick fix? Or did I miss something?

Thank you!

@simonbrunel
Copy link
Member

Can you share the page that generates this issue or a fiddle that reproduces the error?

@Mek89
Copy link
Author

Mek89 commented Jan 4, 2018

Sure. I use it with Rxjs (fiddle):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
	<title>chartjs issue</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
</head>

<body>
    <canvas id="chart"></canvas>
</body>
<script>

    const chart = document.getElementById('chart');
    const ctx = chart.getContext('2d');

    const canvasMousedown$ = Rx.Observable.fromEvent(chart, 'mousedown');
    const canvasMousemove$ = Rx.Observable.fromEvent(chart, 'mousemove');
    const canvasMouseup$ = Rx.Observable.fromEvent(chart, 'mouseup');

    const canvasSelection$ = canvasMousedown$.concatMap((startEvent) => {
      return canvasMousemove$.takeUntil(canvasMouseup$).map((endEvent) => [startEvent, endEvent])
    });

    canvasSelection$.subscribe((events) => {
        console.log(getElements(scatterChart, events));
    });

    var scatterChart = new Chart(ctx, {
        type: 'scatter',
        data: {
            datasets: [{
                label: 'Scatter Dataset',
                data: [{
                    x: -10,
                    y: 0
                }, {
                    x: 0,
                    y: 10
                }, {
                    x: 10,
                    y: 5
                }]
            }]
        },
        options: {
            scales: {
                xAxes: [{
                    type: 'linear',
                    position: 'bottom'
                }]
            }
        }
    });

    function getElements(chart, events) {
        return events.map((event) => chart.getElementAtEvent(event));
    }
</script>
</html>

Thank you for the help!

Edit(SB): code formatting and jsfiddle link

@simonbrunel
Copy link
Member

currentTarget is standardized and should be present on all browsers. I never used RxJS but since it seems to handle events asynchronously, the original event might have been partially discarded at the time you process it.

A workaround would be to restore the currentTarget before calling getElementAtEvent:

function getElements(chart, events) {
  return events.map((event) => {
    event.currentTarget = chart.canvas
    chart.getElementAtEvent(event)
  })
}

@Mek89
Copy link
Author

Mek89 commented Jan 4, 2018

Thank you for the investigation. My only problem with this solution that I use typescript and the event is a const:
" Cannot assign to 'currentTarget' because it is a constant or a read-only property"

@simonbrunel
Copy link
Member

It would be better to figure out why currentTarget is not defined, which is something I would ask to the RxJS community since it's not related to Chart.js. If event.target is defined in your case, we could also consider to fallback to that value in getRelativePosition:

  var canvas = evt.currentTarget || evt.target || evt.srcElement;

@Mek89
Copy link
Author

Mek89 commented Jan 5, 2018

Thank you for the investigation I hope this fallback get into the code some point of the future because rxjs and other similar libraries getting more popular and I think this fallback could mitigate some issues.

@benmccann
Copy link
Contributor

Seems better to solve in RxJS

@benmccann benmccann changed the title getElementAtEvent firefox issue getElementAtEvent rxjs issue Jun 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants