how to change the type of graph using Chart.js?

Asked

Viewed 1,513 times

5

Guys I’m developing an application that helps me build graphics, and I was thinking about doing it in a way where the graph is built dynamically as the user inserts information, the first of them would be the type of chart (if it’s line, 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 exchange of classes, it follows 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 a novice at angular programming so any criticism of the code or suggestion of some other way to do what I want is always welcome! thank you in advance

2 answers

2

You can use the directive ng-if of the angular, thus the div in question will only be part of the DOM once the condition is satisfied. As you requested suggestion also used the Angular 1 Style Guide to make the code 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>

1

Friend here is a proposal to resolve your doubt, maybe the syntax will change a little but the ultimate goal will be the same.

The way I would do it would be this:

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 I’ve helped, see you later.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.