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

undefined error firing while hovering the chart #88

Closed
koin612 opened this issue Mar 4, 2022 · 6 comments
Closed

undefined error firing while hovering the chart #88

koin612 opened this issue Mar 4, 2022 · 6 comments

Comments

@koin612
Copy link

koin612 commented Mar 4, 2022

I'm using chart.js 3.7.1 and chartjs-chart-treemap 2.0.2 in an vue project. The chart renders but when I hover it does not show the tooltip and fires errors in console. Sometimes it worked when the live-server reloaded code and when I've did the imports in main.ts and in the component itself.

chart.esm.js?9b4a:9037 Uncaught TypeError: Cannot read properties of undefined (reading 'call')
    at Tooltip._positionChanged (chart.esm.js?9b4a:9037:1)
    at Tooltip.handleEvent (chart.esm.js?9b4a:9007:1)
    at Object.afterEvent (chart.esm.js?9b4a:9077:1)
    at callback (helpers.segment.js?dd3d:92:1)
    at PluginService._notify (chart.esm.js?9b4a:4922:1)
    at PluginService.notify (chart.esm.js?9b4a:4909:1)
    at Chart.notifyPlugins (chart.esm.js?9b4a:6047:1)
    at Chart._eventHandler (chart.esm.js?9b4a:6074:1)
    at listener (chart.esm.js?9b4a:5952:1)
    at Chart.event (chart.esm.js?9b4a:3214:1)

the component looks like this

<template>
  <canvas ref="canvas" />
</template>

<script lang="ts">
import { Vue, Component, Ref } from "vue-property-decorator";
import { Chart } from "chart.js";
import { TreemapController, TreemapElement } from "chartjs-chart-treemap";
Chart.register(TreemapController, TreemapElement);

@Component
export default class TreemapChart extends Vue {
  @Ref("canvas") canvas!: HTMLCanvasElement;

  ctx2d = null as any;

  mounted(): void {
    this.ctx2d = this.canvas.getContext("2d");
    new Chart(this.ctx2d!, {
      type: "treemap",
      data: {
        datasets: [
          {
            label: "Basic treemap",
            tree: [15, 6, 6, 5, 4, 3, 2, 2],
            spacing: 0.1,
            borderWidth: 2,
            borderColor: "rgba(180,180,180, 0.15)",
          },
        ],
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          title: {
            display: true,
            text: "Basic treemap example",
          },
          legend: {
            display: false,
          },
        },
      },
    } as any);
  }
}
</script>

@kurkle
Copy link
Owner

kurkle commented Mar 4, 2022

Maybe you could try importing and registering Tooltip?

Edit: just to make it clear, the top part:

import { Vue, Component, Ref } from "vue-property-decorator";
import { Chart, Tooltip } from "chart.js";
import { TreemapController, TreemapElement } from "chartjs-chart-treemap";
Chart.register(Tooltip, TreemapController, TreemapElement);

@kurkle
Copy link
Owner

kurkle commented Mar 4, 2022

Also, if a the "Basic treemap example" text is rendered on the chart, I suspect this might be an issue with SSR. You could try disabling that for this component (don't as me how, I don't use Vue).

@koin612
Copy link
Author

koin612 commented Mar 4, 2022

ty for your help. It's client side rendered but the tooltip (I've tried already) import seems like it's working now. I've already imported in main.ts the registerables like:

import { Chart, registerables } from "chart.js";
import { TreemapController, TreemapElement } from "chartjs-chart-treemap";
Chart.register(TreemapController, TreemapElement, ...registerables);

which I think should import Tooltip and don't treeshake. Specifying it explicitly again/twice seems to work from my tests.

@koin612 koin612 closed this as completed Mar 4, 2022
@kurkle
Copy link
Owner

kurkle commented Mar 4, 2022

I've usually created a file for doing the registration like:

chart.js

import { Chart, registerables } from "chart.js";
import { TreemapController, TreemapElement } from "chartjs-chart-treemap";
Chart.register(...registerables, TreemapController, TreemapElement);

export default Chart;

component.js

import Chart from './chart';
...

But the actual fix is probably registering the ...registrables before TreemapController:
Chart.register(...registerables, TreemapController, TreemapElement);

@kurkle
Copy link
Owner

kurkle commented Mar 4, 2022

And the explanation is here, if Tooltip is not registered before TreemapController, the tooltip positioner is not registered.

TreemapController.afterRegister = function() {
const tooltipPlugin = registry.plugins.get('tooltip');
if (tooltipPlugin) {
tooltipPlugin.positioners.treemap = function(active) {
if (!active.length) {
return false;
}
const item = active[active.length - 1];
const el = item.element;
return el.tooltipPosition();
};
}
};

Should probably emit a warning about this.

@koin612
Copy link
Author

koin612 commented Mar 4, 2022

thank you kurkle for analyzing the problem, really appreciate this. I can confirm if I do Chart.register(...registerables, TreemapController, TreemapElement) it works as intended. Kinda makes sense, but I did not expect an order in the register at first glance. Seeing the controller it makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants