Skip to content

Instantly share code, notes, and snippets.

@cybrox
Created June 5, 2014 12:39
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save cybrox/97bca1c3f2cb7c200600 to your computer and use it in GitHub Desktop.
Save cybrox/97bca1c3f2cb7c200600 to your computer and use it in GitHub Desktop.
Use Chart.js as a simple Ember.js component
/**
* This is a very simple example of an ember component to integrate
* nnick/chart.js in an ember.js application. Basically, it is simply
* using the components hook to create a ChartJS canvas element.
* Additionally, it supports an update property that allows you to
* let the chart re-rendet if your data or options change. Chart.js
* doesn't support updating its data so this will just create a new
* chart on the given canvas.
*
* Example usage in a handlebars template:
* {{ember-chart type=CHARTTYPE data=CHARTDATA options=CHARTOPTIONS update=CHARTUPDATE}}
*
* CHARTTYPE: Can be `Line`, `Bar`, `Radar`, `PolarArea`, `Pie` or `Doughnut`.
* CHARTDATA: The chart data array
* CHARTOPTIONS: The chart options array, this can be skipped, the component will genereate {} if this isn't set.
* CHARTUPDATE: Boolean indicator, the chart will re-render on data/options change if set to true. Can be undefined
* For more information, please read the Chart.js doc at http://chartjs.org
*/
App.EmberChartComponent = Ember.Component.extend({
tagName: 'canvas',
setup: false,
/**
* Construction handler
* This will create the canvas and check the given
* input values since Chart.js can react pretty odd
* when getting wrong and/or missing values.
*/
didInsertElement: function(){
canvas = this.get('element');
context = canvas.getContext('2d');
canvas.width = $(canvas).parent().width();
canvas.height = $(canvas).parent().height();
data = this.get('data');
type = this.get('type').charAt(0).toUpperCase() + this.get('type').slice(1);
if(!type.match(/(Line|Bar|Radar|PolarArea|Pie|Doughnut)/)) type = "Line";
options = (this.get('options') !== undefined) ? this.get('options') : {};
this.setProperties({
'_data': data,
'_type': type,
'_canvas': canvas,
'_context': context,
'_options': options
});
this.chartRender();
},
/**
* Render the chart to the canvas
* This function is separated from the event hook to
* allow data overwriting which more or less results
* in updating the chart.
*/
chartRender: function(){
chart = new Chart(this.get('_context'))[this.get('_type')](this.get('_data'),this.get('_options'));
this.setProperties({
'_chart': chart,
'setup': true
});
},
/**
* Chart Update Handler
* This will re-render the chart whenever its data or
* options changes, if the 'update' property is set to true
*/
chartUpdate: function(){
if(this.get('update') === true && this.get('setup') == true){
this.chartRender();
}
}.observes('data', 'options'),
});
@jeprussell
Copy link

@cybrox Really great !! Please could you give me an example how to use pass data and options like label, fillColor, pointColor, etc.

{{ember-chart type=Line data=??? options=??? update=true}}

Thanks keep going

@cybrox
Copy link
Author

cybrox commented Aug 9, 2014

@joseperales Sorry for the late reply, I forgot that Gist doesn't actually create notifications.
You can add controller properties for these options. This is an example on how we use it in production:

the options object: https://github.com/hummingbird-me/hummingbird/blob/master/app/assets/javascripts/controllers/user_index_controller.js#L152
You can use this like a normal object with all options chartjs offers.

the embedded component in the template: https://github.com/hummingbird-me/hummingbird/blob/master/app/assets/javascripts/templates/user/index.hbs#L144

Don't forget to use quotes for the type (type="Line"). Otherwise, Ember would try to send the value of YouController.Line

@alessandro-riz
Copy link

This is a little fix for chartUpdate, I've to set _data and _option to make it work

     /**
     * Chart Update Handler
     * This will re-render the chart whenever its data or
     * options changes, if the 'update' property is set to true
     */
    chartUpdate : function() {
        if (this.get('update') === true && this.get('setup') == true) {
            this.setProperties({
                '_data' : this.get('data'),
                '_options' : this.get('options')
            });
            this.chartRender();
        }
    }.observes('data', 'options')

@kagiasoldaccount
Copy link

This is another fix. We need to destroy stale instances.

      /**
       * Render the chart to the canvas
       * This function is separated from the event hook to
       * allow data overwriting which more or less results
       * in updating the chart.
       */
      chartRender: function(){
        chart = this.get('_chart');
        if (chart !== undefined) {
            chart.destroy();
        }

        chart = new Chart(this.get('_context'))[this.get('_type')](this.get('_data'),this.get('_options'));
        this.setProperties({
          '_chart': chart,
          'setup': true
        });

      },

@PankajWorks
Copy link

@cybrox , The links you posted is not available, Please repost them

@cybrox
Copy link
Author

cybrox commented Mar 7, 2017

@PankajWorks This "implementation" is a hacky 5-minute solution I wrote ages ago.
There is an ember-cli package for implementing chartjs with ember by now. Check it out here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment