Estoy intentando crear un gráfico de barras de GoogleCharts con CategoryFilters que también muestra el promedio de cada categoría / grupo. ¿Cómo calculo y muestro una barra / columna adicional del promedio?

Algo como esto (ejemplo) -> https://ibb.co/wQksgGN

Ya intenté usar líneas de tendencia en la parte de opciones del gráfico, pero son solo líneas, no barras / columnas, y no parece funcionar con mi código.

trendlines: { 3: {}},

Aquí todo mi código hasta ahora -> https://jsfiddle.net/tototatutu/ktwr5jap/5/

2
Tototatutu 16 oct. 2019 a las 19:06

1 respuesta

La mejor respuesta

Porque necesita calcular el promedio antes de que se dibujen los gráficos,
no podrá utilizar la función de panel / enlace.

En su lugar, deberá realizar el cálculo promedio y dibujar los gráficos,
durante el evento de cambio de estado de los controles.

Primero asignamos la tabla de datos a los controles, agregamos el detector de eventos y los dibujamos.

// Define category pickers for 'KPI', 'Peer Group'
var kpiPicker = new google.visualization.ControlWrapper({
  controlType: 'CategoryFilter',
  containerId: 'control1',
  dataTable: data,               // <-- add data table
  options: {
    filterColumnLabel: 'KPI',
    ui: {
      labelStacking: 'vertical',
      allowTyping: false,
      allowMultiple: false,
      caption: 'Choose KPI',
      sortValues: true,
      allowNone: false
  }}
});

var regionPicker = new google.visualization.ControlWrapper({
  controlType: 'CategoryFilter',
  containerId: 'control2',
  dataTable: data,               // <-- add data table
  options: {
    filterColumnLabel: 'Peer Group',
    ui: {
        labelStacking: 'vertical',
        allowTyping: false,
        allowMultiple: false,
        caption: 'Choose Peer Group',
        sortValues: true,
        allowNone: false
    }}
});

// Add state change event listeners
google.visualization.events.addListener(kpiPicker, 'statechange', stateChange);
google.visualization.events.addListener(regionPicker, 'statechange', stateChange);

// Draw controls
kpiPicker.draw();
regionPicker.draw();

A continuación, durante el evento de cambio de estado, creamos una vista de datos y filtramos los datos en función de las categorías seleccionadas.

// Build data view, filter based on category filters
var view = new google.visualization.DataView(data);
view.setRows(view.getFilteredRows([{
  column: 0,
  value: kpiPicker.getState().selectedValues[0]
}, {
  column: 1,
  value: regionPicker.getState().selectedValues[0]
}]));

Luego use el método group para encontrar el promedio de la vista.

// Group data, calculate average
var groupData = google.visualization.data.group(
  view,
  [{column: 0, type: 'string', modifier: function () {return 'Average';}}],
  [{
    column: 3,
    type: 'number',
    label: 'Average',
    aggregation: google.visualization.data.avg
  }]
);

Luego convertimos la vista de datos a una tabla de datos, agregamos la fila promedio y ordenamos.

// Convert view to data table, add average row, sort
view = view.toDataTable();
view.addRow([kpiPicker.getState().selectedValues[0], regionPicker.getState().selectedValues[0], 'Peer Group Average', groupData.getValue(0, 1), '#757575']);
view.sort({column: 3, desc: true});

Luego, asignamos la vista de datos a los gráficos y dibujamos ...

// Draw charts
barChart.setDataTable(view);
table.setDataTable(view);
barChart.draw();
table.draw();

Consulte el siguiente fragmento de trabajo para ver un ejemplo completo ...

google.charts.load('current', {
  packages: ['controls']
}).then(function () {
  // Prepare the data
  var data = google.visualization.arrayToDataTable([
    ['KPI', 'Peer Group', 'Products', 'Amount', { role: 'style' }],
    ['KPI 1', 'EMEA', 'Product A', 4, '#003E7D'],
    ['KPI 1', 'EMEA', 'Product B', 6, '#003E7D'],
    ['KPI 1', 'EMEA', 'Product C', 2, '#F46B1B'],
    ['KPI 1', 'Americas', 'Product A', 3, '#003E7D'],
    ['KPI 1', 'Americas', 'Product B', 8, '#003E7D'],
    ['KPI 1', 'Americas', 'Product C', 7, '#F46B1B'],
    ['KPI 2', 'EMEA', 'Product A', 9, '#003E7D'],
    ['KPI 2', 'EMEA', 'Product B', 1, '#003E7D'],
    ['KPI 2', 'EMEA', 'Product C', 4, '#F46B1B'],
    ['KPI 2', 'Americas', 'Product A', 4, '#003E7D'],
    ['KPI 2', 'Americas', 'Product B', 6, '#003E7D'],
    ['KPI 2', 'Americas', 'Product C', 7, '#F46B1B']
  ]);

  // Define category pickers for 'KPI', 'Peer Group'
  var kpiPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'control1',
    dataTable: data,               // <-- add data table
    options: {
      filterColumnLabel: 'KPI',
      ui: {
        labelStacking: 'vertical',
        allowTyping: false,
        allowMultiple: false,
        caption: 'Choose KPI',
        sortValues: true,
        allowNone: false
    }}
  });

  var regionPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'control2',
    dataTable: data,               // <-- add data table
    options: {
      filterColumnLabel: 'Peer Group',
      ui: {
          labelStacking: 'vertical',
          allowTyping: false,
          allowMultiple: false,
          caption: 'Choose Peer Group',
          sortValues: true,
          allowNone: false
      }}
  });

  // Define a bar chart to show 'Amount' data
  var barChart = new google.visualization.ChartWrapper({
    chartType: 'BarChart',
    containerId: 'chart1',
    options: {
      width: 480,
      height: 300,
      legend: 'none',
      bar: {
          groupWidth: '50%'
      },
      animation: {
          duration: 600,
      },
      hAxis: {
            minValue: 0,
            maxValue: 1,
            ticks: [0, 2, 4, 6, 8, 10],
            gridlines: {
               color: '#F46B1B'
            },
            textStyle: {
               color: '#003E7D',
               fontSize: 15,
               fontName: 'Montserrat',
               bold: true,
            },
         },
      vAxis: {
               textStyle: {
                  fontName: 'Montserrat',
                  color: '#003E7D',
                  fontSize: 11,
                  bold: true
               },
            },
    },
    // Configure the barChart to use columns 2 (Products), 3 (Amount), and 4 (style/colors)
    'view': {'columns': [2, 3, 4]}
  });

  // Define a table.
  // The table shows whatever is selected by the category pickers. It's here
  // just for reference and debugging.
  var table = new google.visualization.ChartWrapper({
    'chartType': 'Table',
    'containerId': 'chart2',
    'options': {
      'width': '400px'
    },
    'view': {'columns': [0, 1, 2, 3]}
  });

  // Add state change event listeners
  google.visualization.events.addListener(kpiPicker, 'statechange', stateChange);
  google.visualization.events.addListener(regionPicker, 'statechange', stateChange);

  // Draw controls
  kpiPicker.draw();
  regionPicker.draw();

  // Draw charts
  stateChange();

  function stateChange() {
    // Build data view, filter based on category filters
    var view = new google.visualization.DataView(data);
    view.setRows(view.getFilteredRows([{
      column: 0,
      value: kpiPicker.getState().selectedValues[0]
    }, {
      column: 1,
      value: regionPicker.getState().selectedValues[0]
    }]));

    // Group data, calculate average
    var groupData = google.visualization.data.group(
      view,
      [{column: 0, type: 'string', modifier: function () {return 'Average';}}],
      [{
        column: 3,
        type: 'number',
        label: 'Average',
        aggregation: google.visualization.data.avg
      }]
    );

    // Convert view to data table, add average row, sort
    view = view.toDataTable();
    view.addRow([kpiPicker.getState().selectedValues[0], regionPicker.getState().selectedValues[0], 'Peer Group Average', groupData.getValue(0, 1), '#757575']);
    view.sort({column: 3, desc: true});

    // Draw charts
    barChart.setDataTable(view);
    table.setDataTable(view);
    barChart.draw();
    table.draw();
  }
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
  <table>
    <tr style='vertical-align: top'>
      <td style='width: 300px; font-size: 0.9em;'>
        <div id="control1" style='margin-top: 50px;'></div>
        <div id="control2" style='margin-top: 10px;'></div>
      </td>
      <td style='width: 600px;'>
        <div style="float: left; margin-top: 50px;" id="chart1"></div>
        <div style="float: left; margin-top: 50px;" id="chart2"></div>
      </td>
    </tr>
  </table>
</div>

NOTA: https://www.google.com/jsapi ya no debe usarse para cargar gráficos de Google,
es una versión antigua .

En su lugar, debería usarse https://www.gstatic.com/charts/loader.js.

Esto solo cambiará la declaración load.

Ver el fragmento de arriba ...

1
WhiteHat 16 oct. 2019 a las 16:43