<html>

<head>
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
</head>

<body itemscope itemtype="http://schema.org/Action">

  <section id="mdx_mainwrap" class="container-fluid">

    <div id="content">
      <div class="site-width">
        <div class="row">

          <section id="mdx_contentmainwrap">

            <section id="mdx_content" class="col-md-9 margin40">

              <article class="mdx_contentmain">
                <div class="content">

                  <div id="postMain" class="">
                    <script type="text/javascript">
                      google.charts.load("current", {
                        "packages": ["corechart", "controls"]
                      });
                      google.charts.setOnLoadCallback(drawDashboard);
                      var chartTable;

                      function drawDashboard() {
                        var dashboard = new google.visualization.Dashboard(
                          document.getElementById('dashboard_div'));
                        var slider = new google.visualization.ControlWrapper({
                          'controlType': 'NumberRangeFilter',
                          'containerId': 'slider_div',
                          'options': {
                            'filterColumnIndex': 7,
                            'minValue': 0,
                            'ui': {
                              'labelStacking': 'vertical',
                              'label': 'Filter Total Cost'
                            }
                          }
                        });
                        var categoryPicker = new google.visualization.ControlWrapper({
                          'controlType': 'CategoryFilter',
                          'containerId': 'categoryPicker_div',
                          'options': {
                            'filterColumnIndex': 1,
                            'ui': {
                              'labelStacking': 'vertical',
                              'label': '',
                              'allowTyping': false,
                              'allowMultiple': true,
                              'sortValues': false,
                              'caption': 'Select types...',
                            }
                          },
                          'state': {
                            'selectedValues': ['ES', 'MS', 'HS', 'Other']
                          }
                        });
                        var pie = new google.visualization.ChartWrapper({
                          'chartType': 'PieChart',
                          'containerId': 'piechart_div',
                          'options': {
                            'width': 300,
                            'height': 300,
                            'legend': 'none',
                            'chartArea': {
                              'left': 15,
                              'top': 15,
                              'right': 0,
                              'bottom': 20
                            },
                            'pieSliceText': 'label',
                            'backgroundColor': 'none'
                          },
                          'view': {
                            'columns': [0, 4]
                          }
                        });
                        // was var...
                        chartTable = new google.visualization.ChartWrapper({
                          'chartType': 'Table',
                          'containerId': 'table_div',
                          'options': {
                            width: '100%',
                             height: '100%',
                            'view': {
                              columns: '[0,4,5]'
                            },
                            'frozenColumns': 1,
                            'allowHtml': true,
                            'cssClassNames': {
                              headerRow: 'chartHrow',
                              headerCell: 'chartHcell'
                            }
                          }
                        });
                        var data = google.visualization.arrayToDataTable([
                          ['Facility', 'Type', 'Seismic Repairs (AB 300)', 'Immediate Repairs', 'Replacement Reserves (Years 1-10)', 'Capital Needs Total (Years 0-10)', 'Long-Term Items (Years 11-19)', 'Deficiency Repair Total (Years 0-19)'],
                          ["Arovista ES", "ES", 9773623, 34067, 3904557, 3938624, 4800801, 8739425],
                          ["Brea Canyon HS", "HS", 0, 500, 327381, 327881, 1017027, 1344908],
                          ["Country Hills ES", "ES", 0, 800, 2447310, 2448110, 3159236, 5607346],
                          ["Brea Junior High", "MS", 0, 47310, 3933834, 3981144, 8086874, 12068018],
                          ["Brea Olinda HS", "HS", 0, 321681, 13923920, 14245601, 14018951, 28264552],
                          ["Laurel ES", "ES", 0, 37505, 3440119, 3477624, 1907789, 5385413],
                          ["Mariposa ES", "ES", 0, 37500, 2011502, 2049002, 1014543, 3063545],
                          ["Olinda ES", "ES", 0, 8500, 2116616, 2125116, 4002565, 6127681],
                          ["Fanning ES", "ES", 652360, 0, 3696242, 3696242, 3810302, 7506544],
                          ["M&O Building", "Other", 0, 23676, 573511, 597187, 239542, 836729],
                        ]);
                        // Code to use a CategoryFilter as a column selector
                        // by Andrew Gallant is licensed under a Creative Commons
                        // Attribution-NonCommercial-ShareAlike 3.0 Unported License
                        // see http://jsfiddle.net/asgallant/WaUu2/ for original source
                        // <<modified by Michael Ellars of DLR Group>>
                        // start code for CategoryFilter column selector by Andrew Gallant
                        var columnsTable = new google.visualization.DataTable();
                        columnsTable.addColumn('number', 'colIndex');
                        columnsTable.addColumn('string', 'colLabel');
                        var initState = {
                          selectedValues: []
                        };
                        // put the columns into this data table (skip column 0<<and 1>>)
                        for (var i = 2; i < data.getNumberOfColumns(); i++) {
                          columnsTable.addRow([i, data.getColumnLabel(i)]);
                          // you can comment out this next line if you want
                          // to have a default selection other than the whole list
                          //initState.selectedValues.push(data.getColumnLabel(i));
                        }
                        // you can set individual columns to be the default columns
                        // (instead of populating via the loop above) like this:
                        initState.selectedValues.push(data.getColumnLabel(7));
                        var columnFilter = new google.visualization.ControlWrapper({
                          controlType: 'CategoryFilter',
                          containerId: 'colFilter_div',
                          dataTable: columnsTable,
                          options: {
                            filterColumnLabel: 'colLabel',
                            ui: {
                              labelStacking: 'vertical',
                              label: 'Cost Column to Visualize:',
                              allowTyping: false,
                              allowMultiple: false, // <<was true>>
                              allowNone: false,
                              sortValues: false, // <<added>>
                              selectedValuesLayout: 'belowStacked'
                            }
                          },
                          state: initState
                        });

                        function setChartView() {
                          var state = columnFilter.getState();
                          var row;
                          var view = {
                            columns: [0]
                          };
                          for (var i = 0; i < state.selectedValues.length; i++) {
                            row = columnsTable.getFilteredRows([{
                              column: 1,
                              value: state.selectedValues[i]
                            }])[0];
                            view.columns.push(columnsTable.getValue(row, 0));
                          }
                          // sort the indices into their original order
                          view.columns.sort(function(a, b) {
                            return (a - b);
                          });
                          pie.setView(view);
                          pie.draw();
                          // <<added these remaining lines to tie into slider control>>
                          var label = 'Filter by ' + state.selectedValues[0] + ' Cost:';
                          slider.setOption('ui', {
                            'labelStacking': 'vertical',
                            'label': label,
                            'format': {
                              pattern: '$###,###'
                            }
                          });
                          slider.setOption('filterColumnIndex', columnsTable.getValue(row, 0));
                          slider.draw();
                          for (var i = 0; i < 8; i++) { // manually update i=number to actual column count
                            data.setColumnProperty(i, 'className', 'chartHcell');
                          }
                          data.setColumnProperty(columnsTable.getValue(row, 0), 'className', 'chartHighlight');
                          //  data.setColumnProperty(columnsTable.getValue(row, 0), 'className', 'chartHighlight');
                        }
                        google.visualization.events.addListener(columnFilter, 'statechange', setChartView);
                        setChartView();
                        columnFilter.draw();
                        // end code for CategoryFilter column selector by Andrew Gallant
                        var usdFormatter = new google.visualization.NumberFormat({
                          pattern: '$###,###'
                        });
                        usdFormatter.format(data, 2);
                        usdFormatter.format(data, 3);
                        usdFormatter.format(data, 4);
                        usdFormatter.format(data, 5);
                        usdFormatter.format(data, 6);
                        usdFormatter.format(data, 7);

                        function jumpToSite() {
                          // note that you have to insert "getChart()" 
                          // between chartTable and getSelection() in order
                          // to access the selection through the dashboard
                          var selection = chartTable.getChart().getSelection();
                          var message = '';
                          var view = chartTable.getDataTable();
                          for (var i = 0; i < selection.length; i++) {
                            var item = selection[i];
                            if (item.row != null && item.column != null) {} else if (item.row != null) {
                              // references view instead of data 
                              message = view.getFormattedValue(item.row, 0);
                            } else if (item.column != null) {
                              // references view instead of data
                              message = view.getFormattedValue(0, item.column);
                            }
                          }
                          var jump = "#" + message + "costs";
                          document.location.hash = jump;
                        }
                        google.visualization.events.addListener(chartTable, 'select', jumpToSite);
                        dashboard.bind([slider, categoryPicker], [pie, chartTable]);
                        // added next two lines per Brian Nolan's bootstrap table row
                        google.visualization.events.addListener(chartTable, 'ready', calcTotal);
                        google.visualization.events.addOneTimeListener(chartTable, 'ready', addSortListener);
                        dashboard.draw(data);
                        // added this function per Brian Nolan's bootstrap table row
                        function addSortListener() {
                          google.visualization.events.addListener(chartTable.getChart(), 'sort', calcTotal);
                        }
                      }

                      function calcTotal() {
                        var filteredData = chartTable.getDataTable();
                        var columnIndicesToTotal = [2, 3, 4, 5, 6, 7]; // which columns have sums
                        var totals = {}
                        for (var i = 0; i < columnIndicesToTotal.length; i++) {
                          var total = 0;
                          for (var row = 0; row < filteredData.getNumberOfRows(); row++) {
                            total += filteredData.getValue(row, columnIndicesToTotal[i]);
                          }
                          totals[columnIndicesToTotal[i]] = total;
                        }
                        displayTotals(filteredData, totals);
                      }

                      function displayTotals(filteredData, totals) {
                        var htmlString;
                        htmlString = '<tr class="google-visualization-table-tr-even chartHrow">';
                        htmlString += '<td class="google-visualization-table-td">Totals:</td>';
                        for (var col = 1; col < filteredData.getNumberOfColumns(); col++) {
                          if (totals[col]) {
                            var tempSum = '$' + totals[col].toLocaleString('en');
                            htmlString += '<td class="google-visualization-table-td google-visualization-table-td-number chartHcell">' + tempSum + '</td>';
                          } else {
                            htmlString += '<td class="google-visualization-table-td google-visualization-table-td-bool">&nbsp;</td>';
                          }
                        }
                        htmlString += '</tr>';
                        $('#table_div').find('table').append(htmlString);
                      }
                    </script>

                    <div id="dashboard_div">

                      <table width=100%>
                        <tr>
                          <td>
                            <div id="piechart_div" align="center"></div>
                            <div id="colFilter_div" align="center" style="padding: 1em"></div>

                          </td>
                          <td>
                            <div id="slider_div" width="100" align="center" style="padding: 1em"></div>
                            <div id="categoryPicker_div" align="center" style="padding: 1em"></div>

                          </td>
                        </tr>
                        <tr>
                          <td>
                          </td>

                        </tr>
                      </table>
                                                                            <div id="table_div" width=100%></div>

                    </div>
                    <hr/>
                  </div>
                </div>
              </article>
            </section>
          </section>
        </div>
      </div>
    </div>
  </section>
  </div>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</body>

</html>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.