question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Extending chart in order to override draw function

See original GitHub issue

I’d love extend the functionality of the bar chart by making it draw rounded bars instead of the standard ones. Here is a fiddle of how it can be realized out of vue.js context: http://jsfiddle.net/0dzp3jxw/

How can I possibly do that in vue-chartjs?

Currently I’m even struggling to find out how to create a custom chart and let the actual chart extend from that (intermediate heredity between native chart and used chart).

I created a chart like this:

# RoundedCorners.vue
<script>
import { Bar, mixins } from 'vue-chartjs'

export default {
  extends: Bar,
  mixins: [mixins.reactiveProp],
  props: ['chartData', 'options'],
  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}
</script>

If I then create the actual chart and let it extend the newly created custom chart like this:

# FinancesChart
<script>
import { mixins } from 'vue-chartjs'
import { RoundedCorners} from './RoundedCorners'

export default {
  extends: RoundedCorners,
  mixins: [mixins.reactiveProp],
  props: ['chartData', 'options'],
  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}
</script>

it says Failed to mount component: template or render function not defined. and this.renderChart is not a function.

So two questions: 1.) How would I create a three step heritage 2.) How could I then override the initialize or draw function like in the above code snippet?

Thanks a lot!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
Schnodderbalkencommented, Apr 23, 2018

After having gained a little bit of understanding about the above mentioned (newer?) interface I was able to make it work. The animation is missing and there is a little clipping error but for everyone being interested in this it could be a good starting point.

<script>
  import Chart from 'chart.js'
  import { generateChart } from 'vue-chartjs'

  // Extend on of the default charts
  // http://www.chartjs.org/docs/latest/developers/charts.html
  Chart.defaults.RoundedBarChart = Chart.defaults.bar;
  Chart.controllers.RoundedBarChart = Chart.controllers.bar.extend({
    name: "RoundedBarChart",
    initialize: function (data) {
     Chart.controllers.bar.prototype.initialize.apply(this, arguments)

      let me = this
      let chart = me.chart
      let scale = me.getValueScale()
      let meta = me.getMeta()
      let rects = meta.data
      let dataset = me.getDataset()
      let ilen = rects.length
      let i = 0
      let rectangleDraw = rects[0].draw

      for (; i < ilen; ++i) {
        let rightValue = scale.getRightValue(dataset.data[i])

        if (!isNaN(rightValue)) {
          rects[i].draw = function() {
            if (typeof meta.data[0]._model === 'undefined') {
              return
            }

            const radius =  meta.data[0]._model.width * 0.5;
            const bar = meta.data[this._index]._model
            // draw the original bar a little down (so that our curve brings it to its original position)
            const y = bar.y
            // the min is required so animation does not start from below the axes
            bar.y = Math.min(bar.y + radius, scale.maxHeight - 1)
            // adjust the bar radius depending on how much of a curve we can draw
            const barRadius = (bar.y - y)
            rectangleDraw.apply(this, arguments)

            // draw a rounded rectangle on top
            Chart.helpers.drawRoundedRectangle(chart.ctx, bar.x - bar.width / 2, bar.y - barRadius + 1, bar.width, bar.base, barRadius)
            chart.ctx.fill();

            // restore the y value
            bar.y = y
          }
        }
      }
    }
  })

  export const RoundedCorners = generateChart('rounded-bar-chart', 'RoundedBarChart')
</script>

https://github.com/chartjs/Chart.js/blob/master/src/controllers/controller.bar.js#L445 Having had a look at the implementation of the original draw function was quite helpful for me.

3reactions
aperturelesscommented, Apr 18, 2018

Well there are two ways.

  1. You really overwrite the default Bar Chart.
  2. You create your own “rounded-bar-chart”

Overwriting

You need to import the Chart.js object into your component. Then you can overwrite everything in there.

However with this approach you will overwrite the default Bar chart. So all your bar charts will have rounded corners.

# RoundedCorners.vue
<script>
import Chart from 'chart.js'
import { Bar, mixins } from 'vue-chartjs'

Chart.types.Bar.extend()


export default {
  extends: Bar,
  mixins: [mixins.reactiveProp],
  props: ['chartData', 'options'],
  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}
</script>

This should work tho.

Custom Chart

As mentioned here #326 You can however also create your own custom chart. By using the generateChart helper.

You create a new chart type LineWithLine or BarRounded extend the default chart.

// 1. Import Chart.js so you can use the global Chart object
import Chart from 'chart.js'
// 2. Import the `generateChart()` method to create the vue component.
import { generateChart } from 'vue-chartjs'

// 3. Extend on of the default charts
// http://www.chartjs.org/docs/latest/developers/charts.html
Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({ /* custom magic here */})

// 4. Generate the vue-chartjs component
// First argument is the chart-id, second the chart type.
const CustomLine = generateChart('custom-line', 'LineWithLine')

// 5. Extend the CustomLine Component just like you do with the default vue-chartjs charts.

export default {
  extends: CustomLine,
  mounted () {
    // ....
  }
}

http://vue-chartjs.org/#/home?id=custom-new-charts

Read more comments on GitHub >

github_iconTop Results From Across the Web

Chart.Js V2.6.0 draw function override - CodePen
If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the...
Read more >
Change the plotting order of categories, values, or data series
Reverse the plotting order of categories or values in a chart · Click a chart. This displays the Chart Tools. · Under Chart...
Read more >
vue-chartjs extend chart override draw function not working
Show activity on this post. I am trying to customize a chart by override the draw function like done in this example:.
Read more >
How to Create a Dynamic Chart Range in Excel
Learn how to create a dynamic chart range that instantly updates Excel charts when the data changes. Done using OFFSET and INDEX function....
Read more >
New Charts | Chart.js
Chart.js 2.0 introduced the concept of controllers for each dataset. ... line controller draw: function() {}, // Initializes the controller ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found