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.

Example to create gradient background for chart from child component canvas context

See original GitHub issue

Expected Behavior

This question has been asked before at https://stackoverflow.com/questions/51022003/vue-chartjs-create-gradient-background-for-chart-from-child-component-canvas. However I think a lot of people would benefit from an example in the documentation somewhere.

The author in this article like me was ‘confused’ as to what was meant by “…pass in all data as props” . I still don’t know what I need to do to get this working. My scenario is exactly the same as the author.

The actual reusable chart code is:


export default {
    extends: Bar,
    gradient: null,
    mixins: [mixins.reactiveProp],
    props: ['chartData', 'options'],
    mounted() {

        var gradientStroke = this.$refs.canvas.getContext('2d').createLinearGradient(0, 230, 0, 50);

        gradientStroke.addColorStop(1, 'rgba(253,93,147,0.8)');
        gradientStroke .addColorStop(0, 'rgba(253,93,147,0)'); //blue colors

//I don't know what to do with it here. Because if the chart isn't reusable and I add my chartdata here it works fine. But I want it to be reusable

        this.renderChart(this.chartData, this.options);
        
    }
};

Actual Behavior

Then in my parent code:

                labels: labels,
                datasets: [{
                    label: 'Name',
                    fill: true,
                    backgroundColor: '#ff5991',
                    hoverBackgroundColor: '#ff5991',
                    borderColor: '#ff5991',
                    borderWidth: 2,
                    borderDash: [],
                    borderDashOffset: 0.0,
                    data: chartdata
                }]
            };

Please can we add an example for this as I know this is for issues only but there isn’t anyone or Gittur to talk to.

Many thanks

Environment

  • vue.js version: 2.5.17
  • vue-chart.js version: 3.4.0
  • npm version: -/-

Issue Analytics

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

github_iconTop GitHub Comments

4reactions
aperturelesscommented, Nov 14, 2018

Well, if you want a reuseable chart, it depends on mulitple factors, because there are multiple ways of doing it.

The more generic the solution should be, the more complex it will get.

The questions are, what should be reuseable and configurable?

The easiest solution is if you just have a line chart for example with only one dataset. And the colors/gradients are fixed.

import {Line} from 'vue-chartjs'

export default {
  extends: Line,
  props: {
    labels: {
      type: Array,
      default: () => ['A', 'B', 'C']
    },
    datalabel: {
       type: String,
       default: 'Downloads per Week'
    },
    chartdata: {
	  type: Array,
      default: () => [100, 40, 106]
    }
  },
  data () {
    return {
      gradient: null
    }
  },
  mounted () {
    this.gradient = this.$refs.canvas.getContext('2d').createLinearGradient(0, 0, 0, 450)


    this.gradient.addColorStop(0, 'rgba(255, 0,0, 0.5)')
    this.gradient.addColorStop(0.5, 'rgba(255, 0, 0, 0.25)');
    this.gradient.addColorStop(1, 'rgba(255, 0, 0, 0)');



    this.renderChart({
      labels: this.labels,
      datasets: [
        {
          label: this.datalabel,
          borderColor: '#FC2525',
          pointBackgroundColor: 'white',
          borderWidth: 1,
          pointBorderColor: 'white',
          backgroundColor: this.gradient,
          data: this.chartdata
        }
      ]
    }, {responsive: true, maintainAspectRatio: false})

  }
}

This way, you can pass in your data, labels etc. and have a reuseable chart.

You could also make it a bit simpler if you use the rest/spread operator.

Chart with spread

import {Line} from 'vue-chartjs'

export default {
  extends: Line,
  props: {
    labels: {
      type: Array,
      default: () => ['A', 'B', 'C']
    },
    chartconfig: {
       type: Object,
       default: () => {
          label: 'My Data',
          borderColor: '#FC2525',
          pointBackgroundColor: 'white',
          borderWidth: 1,
          pointBorderColor: 'white',
          data: [10, 11, 12]
       }
    }
  },
  data () {
    return {
      gradient: null
    }
  },
  mounted () {
    this.gradient = this.$refs.canvas.getContext('2d').createLinearGradient(0, 0, 0, 450)


    this.gradient.addColorStop(0, 'rgba(255, 0,0, 0.5)')
    this.gradient.addColorStop(0.5, 'rgba(255, 0, 0, 0.25)');
    this.gradient.addColorStop(1, 'rgba(255, 0, 0, 0)');



    this.renderChart({
      labels: this.labels,
      datasets: [
        {
          ...this.chartconfig
          backgroundColor: this.gradient,
        }
      ]
    }, {responsive: true, maintainAspectRatio: false})

  }
}

This way you are setting the backgroundColor gradient and the rest of the data and config comes over your vue props.


It becomes a bit more complicated if you want configurable gradients. If you just want different colors you can pass in the gradient colors as props and then in your mounted() hook just reference them

this.gradient.addColorStop(0, '`${this.gradientColor1}`')

If you want more configuration you have to write a small generateGradient helper, which takes his data from props or a gradient Object which is a prop.

For example

// Example object with your configuration for your gradient.
const settings = {
 gradientColorStops: 3,
 colorStopValues: [0, 0.5, 1],
 colorStopColors: ['rgba(...)', 'rgba(...)', 'rgba(...)']
}
...

props: {
 gradient: {
  type: Boolean,
  default: true
 }
 gradientSettings: {
   type: Object,
   default: () => {}
 }
}
....

mounted () {
  if (this.gradient) {
    this.generateGradient()
   // in generateGradient you can iterate over the values you got passed in your gradientSettings for (let i = 0; i < this.gradientSettings.gradientColorStops; i++)

  }
},
0reactions
maciz84commented, Nov 14, 2018

Thanks anyway you have been most helpful and I appreciate the library a lot 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

(Vue, ChartJS) Create gradient background for chart from ...
$refs.canvas is undefined in the parent component, which prevents me from getting the context, so I can't create a gradient.
Read more >
CanvasRenderingContext2D.createLinearGradient() - Web APIs
This example initializes a linear gradient using the createLinearGradient() method. Three color stops between the gradient's start and end ...
Read more >
Implementing HTML Canvas and CSS color gradients ...
Let's start by creating a component with a canvas element. We will use a reference to access the 2D context and start our...
Read more >
HTML canvas createLinearGradient() Method - W3Schools
The createLinearGradient() method creates a linear gradient object. The gradient can be used to fill rectangles, circles, lines, text, etc.
Read more >
[Solved]-Horizontal gradient for every single bar in group chart js ...
Coding example for the question Horizontal gradient for every single bar in ... Create gradient background for chart from child component canvas context...
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 Reddit Thread

No results found

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