2

I'm trying to use billboard.js as a simple alternative to d3.js for displaying some line graphs. Unfortunately, I can't seem to get it working in my own repository, nor can I get it working in a vanilla Vue project.

Can anyone tell me if something special is required to get billboard.js up and running in combination with Vue?

My App.vue:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <div id="chart">
  </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { bb } from 'billboard.js';

@Component
export default class App extends Vue {
  mounted() {
    console.log(this);
    console.log(bb);
    bb.generate({
      bindto: '#chart',
      data: {
        columns: [
          ['data1', 30, 200, 100, 170, 150, 250],
        ],
        types: {
          data1: 'line',
          data2: 'area-spline',
        },
        colors: {
          data1: 'red',
          data2: 'green',
        },
      },
    });
  }
}
</script>

And the error code I get from my devtools:

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in mounted hook: "TypeError: $$.generatePoint is not a function"

found in

---> <App> at src/App.vue
       <Root>

For what it's worth, I am using the following npm versions for this project:

  "dependencies": {
    "billboard.js": "^2.0.3",
    "core-js": "^3.6.5",
    "vue": "^2.6.11",
    "vue-class-component": "^7.2.3",
    "vue-property-decorator": "^8.4.2"
  },

I've created a small repository with the minimum code required to reproduce this issue.

tony19
  • 125,647
  • 18
  • 229
  • 307
Benjamin Diele
  • 1,177
  • 1
  • 10
  • 26

1 Answers1

4

Based on the docs, the correct usage for the ESM build is:

// BEFORE:
//import { bb } from 'billboard.js';

// AFTER:
import bb, { line, areaSpline } from 'billboard.js';


export default {
  mounted() {
    bb.generate({
      //...
      data: {
        types: {
          // BEFORE:
          //data1: 'line',
          //data2: 'area-spline',

          // AFTER:
          data1: line(),
          data2: areaSpline(),
        },
      }
    });
  }
}

Also, if you intend to have multiple instances of this chart component on a page, you should pass unique references to the chart's parent element via a ref:

<template>
  <!-- BEFORE: -->
  <!-- <div id="chart" /> -->

  <!-- AFTER: -->
  <div ref="chart" />
</template>

<script>
export default {
  async mounted() {
    // wait til next tick for `ref` to be available below
    await this.$nextTick();

    bb.generate({
      //...
      bindto: this.$refs.chart,
    });
  }
}
</script>

GitHub PR with fixes

tony19
  • 125,647
  • 18
  • 229
  • 307