0

For some data visualisation I use ractive and chart.js. The initial drawing works great, but I can't find a way to update the chart automatically when my data changes. So far I got (simplified):

const Stats = '<canvas id="myChart" width="400" height="400"></canvas>'
    new Ractive ({
        el: '#stats',
        template: Stats,
        magic: true,
        modifyArrays: true,
        data: {docs}, // <= some JSON Data
        computed: {
            Data1() {
                let tempList = this.get('docs');
                // rearrange & filter Data 
                return tempList ;
            },
            Data2() {
                let tempList2 = this.get('docs');
                // rearrange & filter Data 
                return tempList2 ;
            },
            Data3() {
                let tempList3 = this.get('docs');
                // rearrange & filter Data 
                return tempList3 ;
            },
            }

        },
        onrender: function () {
            let DataSet1 = this.get('Data1');
            let DataSet2 = this.get('Data2');
            let DataSet3 = this.get('Data3');
            let ctx = document.getElementById("myChart");
            var myChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: ["Data 1", "Data 1", "Data 3"],
                    datasets: [{
                        label: 'All my Data',
                        data: [DataSet1.length, DataSet2.length, DataSet3.length],
                        backgroundColor: [
                            'rgba(255, 99, 132, 0.2)',
                            'rgba(255, 159, 64, 0.2)',
                            'rgba(75, 192, 192, 0.2)'
                        ],
                        borderColor: [
                            'rgba(255,99,132,1)',
                            'rgba(255, 159, 64, 1)',
                            'rgba(75, 192, 192, 1)'
                        ],
                        borderWidth: 1
                    }]
                },
                options: {
                    responsive: false
                }
            });

        },
        onchange: function () {
            let newData = this.get('docs')
            addData(myChart, label, newData)
            function addData(chart, label, data) {
                chart.data.labels.push(label);
                chart.data.datasets.forEach((dataset) => {
                    dataset.data.push(data);
                });
                chart.update();
            }
        }
    }); 

Of Course I get an error in line chart.data.labels.push(label);, and also I'm quite sure that I would need my computed values in the onrenderfunction, not the initial Dataset. But I really have no clue how to get those into the update function, or if this function is the correct approach at all...

Torf
  • 1,154
  • 11
  • 29

2 Answers2

1

If you are working with 3rd party plugins I would recommend to use Ractive's decorators. This post on ractivejs-and-jquery-plugins shows you a starting point how to implement a decorator based on a fileupload control.

In your case I would recommend to build a decorator with the data as parameter and do not forget to implement the UPDATE function (where in your case you gonna call the update method with the new data for your chart)

nhaberl
  • 417
  • 1
  • 4
  • 17
  • Thanks for the hint, but do you happen to know any good instructions on how to use them? The ractive docs on decorators are not extremely helpful. The best I could find was this [link]http://parhelium.pl/post/How_to_write_a_tooltip_decorator_in_RactiveJS/[link], but for my beginners level it is still to complicated. – Torf Oct 30 '17 at 05:05
  • The best is the link I have added to my answer in combination with the link you mentioned – nhaberl Oct 30 '17 at 05:56
0

As I could not figure out how to write my own decorator for Chart.js I thought I post the solution that worked for me. I do not think it's best practice and for sure decorators would be a better way (therefore I do not mark this solution as correct answer), but it works:

const Stats = '<canvas id="myChart" width="400" height="400"></canvas>'
new Ractive ({
    el: '#stats',
    template: Stats,
    magic: true,
    modifyArrays: true,
    data: {docs}, // <= some JSON Data
    computed: {
        Data1() {
            let tempList = this.get('docs');
            // rearrange & filter Data 
            return tempList ;
        },
        Data2() {
            let tempList2 = this.get('docs');
            // rearrange & filter Data 
            return tempList2 ;
        },
        Data3() {
            let tempList3 = this.get('docs');
            // rearrange & filter Data 
            return tempList3 ;
        },
        }

    },
    onrender: function () {
        let DataSet1 = this.get('Data1');
        let DataSet2 = this.get('Data2');
        let DataSet3 = this.get('Data3');
        let ctx = document.getElementById("myChart");
        myChart = new Chart(ctx, { 
            type: 'doughnut',
            data: {
                labels: ["Data 1", "Data 1", "Data 3"],
                datasets: [{
                    label: 'All my Data',
                    data: [DataSet1.length, DataSet2.length, DataSet3.length]
                }]
            }
        });

    },
    onchange: function () { 
        let changedData1 = this.get('Data1');
        let changedData2 = this.get('Data2');
        let changedData3 = this.get('Data3');
        myChart.data.datasets[0].data[0] = changedData1.length;
        myChart.data.datasets[0].data[1] = changedData2.length;
        myChart.data.datasets[0].data[2] = changedData3.length;
        myChart.update();
        }
    }
}); 
Torf
  • 1,154
  • 11
  • 29