how to change the chart type using chart.js?

5
I'm developing an application that helps me build graphs, and was thinking of doing in a way that the graph is built dynamically as the user inputs information, the first one being the type of chart (if it's line, of bar, pizza, etc.) I made a test with fixed values and the graph is generated perfectly, so I started to make it dynamic, but when I choose the type of graph the system does not update with the class exchange, follow my code:

Controller

        $scope.grafico = {
            labels: ["January", "February", "March", "April", "May", "June", "July"],
            series: ['Series A', 'Series B'],
            data: [
                [65, 59, 80, 81, 56, 55, 40],
                [28, 48, 40, 19, 86, 27, 90]
            ]
        }

        $scope.tipoGrafico = "";

HTML

    <div class="bloco grafico">
        <canvas 
            class="chart {{tipoGrafico}}" 
            chart-data="grafico.data" 
            chart-labels="grafico.labels" 
            chart-series="grafico.series"
            chart-legend="false">
        </canvas>
    </div>
    <label>
        Tipo de Gráfico
        <select ng-model="tipoGrafico">
            <option value="chart-line">Linha</option>
            <option value="chart-bar">Barra</option>
            <option value="chart-pie">Pizza</option>
        </select>
    </label>

I'm new to programming angular so any criticism of the code or suggestion of some other way of doing what I want is always welcome! Thank you in advance.

    
asked by anonymous 14.05.2016 / 17:11

2 answers

2

You can use the ng-if of angular directive, so the div in question will only become part of the DOM once the condition is satisfied. As you requested, I also used the Angular 1 Style Guide for the code to stay a little more readable.

(function() {
  'use strict';
  
  angular
    .module('appGrafico', ["chart.js"]);

  angular
    .module('appGrafico')
    .controller('GraficoController', GraficoController);

  GraficoController.$inject = [];
  
  function GraficoController() {
    var grafico = this;
    
    iniciar();
    
    function iniciar() {
      grafico.configuracoes = {
        tipo: "chart-line",
        labels: ["January", "February", "March", "April", "May", "June", "July"],
        series: ['Series A', 'Series B'],
        data: [
          [65, 59, 80, 81, 56, 55, 40],
          [28, 48, 40, 19, 86, 27, 90]
        ]
      }
    }
  }
})();
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<script src="//cdn.jsdelivr.net/angular.chartjs/latest/angular-chart.min.js"></script>

<div ng-app="appGrafico" style="height: 50%; width: 50%">
  <div ng-controller="GraficoController as grafico">
    <label>
        Tipo de Gráfico
        <select ng-model="grafico.configuracoes.tipo">
          <option value="chart-line">Linha</option>
          <option value="chart-bar">Barra</option>
          <option value="chart-pie">Pizza</option>
        </select>
    </label>
    <div class="bloco grafico">
      <canvas class="chart-line"
              chart-data="grafico.configuracoes.data" 
              chart-labels="grafico.configuracoes.labels" 
              chart-series="grafico.configuracoes.series"
              chart-legend="false"
              ng-if="grafico.configuracoes.tipo === 'chart-line'">
      </canvas>
      <canvas class="chart-bar"
              chart-data="grafico.configuracoes.data" 
              chart-labels="grafico.configuracoes.labels" 
              chart-series="grafico.configuracoes.series"
              chart-legend="false"
              ng-if="grafico.configuracoes.tipo === 'chart-bar'">
      </canvas>
      <canvas class="chart-pie"
              chart-data="grafico.configuracoes.data" 
              chart-labels="grafico.configuracoes.labels" 
              chart-series="grafico.configuracoes.series"
              chart-legend="false"
              ng-if="grafico.configuracoes.tipo === 'chart-pie'">
      </canvas>
    </div>
  </div>
</div>
    
19.11.2016 / 10:34
1

Friend here is a proposal to resolve your question, maybe the syntax changes a bit but the final goal will be the same.

The way I would do it would be as follows:

JS

(function() {
    'use strict';
    angular.module('hello').controller('TesteController', testeController);

    testeController.$inject = ['$scope'];

    function testeController($scope){

        var ctx = document.getElementById("myChart");

        init();

        function init(){
            construirGrafico('bar');
        }

        function construirGrafico(tipoGrafico){
            var myBarChart = new Chart(ctx, {
                type: tipoGrafico,
                data: {
                        labels: ["January", "February", "March", "April", "May", "June"],
                        datasets: [
                            {
                                data: [2500, 1902, 1041, 610, 1245, 952]
                            },
                            {
                                data: [3104, 1689, 1318, 589, 1199, 1436]
                            }
                        ]
                    },
                options: {
                        scales: {
                            yAxes: [{
                                display: false,
                                ticks: {
                                    beginAtZero:true
                                }
                        }]
                    }
                }
            });
        }


        $scope.alterarTipoGrafico = function(){
            construirGrafico($scope.tipo);
        }

    }
})();

HTML:

<div><canvas id="myChart"></canvas></div>
<label>
    Tipo de Gráfico
    <select ng-change="alterarTipoGrafico()" ng-model="tipo">
        <option value="line">Linha</option>
        <option value="bar">Barra</option>
        <option value="pie">Pizza</option>
    </select>
</label>

I hope to have helped, even more.

    
09.06.2016 / 23:53