【问题标题】:Google charts LineGraph switching datatables and maintaining state谷歌图表 LineGraph 切换数据表和维护状态
【发布时间】:2016-04-06 05:02:58
【问题描述】:

我已经调整了我在网上找到的一些示例,这些示例允许我在单击系列时删除/变灰(图例或线条本身)。

然后我想添加在数据表之间切换的功能,并将隐藏/灰色的内容转移到新的数据表。

我的想法来自于从 https://developers.google.com/chart/interactive/docs/animation#value-changes 切换数据 (我的图表没有像示例那样正确动画)

我的问题是当我点击“切换”按钮和切换数据表时,我得到了非常奇怪的结果,有时它会保持正确的选择,但是当你点击一个不同的系列时,一个会神奇地出现,或者它会取消选择一个不同的系列那个点击了。我想不通,所以两个数据表都保持相同的选择(选择意味着灰色/删除的系列)。

值得注意的是

         columns.push({
            calc: 'stringify',
            sourceColumn: i,
            type: 'string',
            role: 'annotation'
         });

正在添加隐藏列以辅助该系列的其他逻辑。虽然我目前没有直接使用它,但我希望它保持并正常工作,因为我认为我将来会使用它。这些“隐藏”的列增加了我认为错误所在的复杂性。

代码在这里:

var button = document.getElementById('b1');
var current = 0;
var data = [];
var chart;
var options;
var ms2 = [{
   "LOCAL_ID": "W-133",
   "Class1": 29,
   "Class2": 3628,
   "Class3": 159,
   "Class4": 24,
   "Class5": 65,
   "Class6": 12,
   "Class7": 0,
   "Class8": 12,
   "Class9": 110,
   "Class10": 41,
   "Class11": 0,
   "Class12": 0,
   "Class13": 0
}, {
   "LOCAL_ID": "14-6A-060",
   "Class1": 19,
   "Class2": 290,
   "Class3": 224,
   "Class4": 0,
   "Class5": 0,
   "Class6": 0,
   "Class7": 0,
   "Class8": 2,
   "Class9": 0,
   "Class10": 0,
   "Class11": 1,
   "Class12": 0,
   "Class13": 0
}, {
   "LOCAL_ID": "45-5-006",
   "Class1": 7,
   "Class2": 191,
   "Class3": 165,
   "Class4": 0,
   "Class5": 6,
   "Class6": 3,
   "Class7": 0,
   "Class8": 4,
   "Class9": 18,
   "Class10": 11,
   "Class11": 0,
   "Class12": 0,
   "Class13": 10
}];



google.charts.load('current', {
   'packages': ['line']
});

google.charts.setOnLoadCallback(init);


button.onclick = function() {
   current = 1 - current;
   button.disabled = true;
   options.chart['subtitle'] = (current ? 'View 1' : 'View 2');
   chart.draw(data[current], options);
};


function getData() {
   var data = new google.visualization.DataTable();

   data.addColumn('number', 'Class');
   ms2.forEach(function(masterLocation, index) {
      data.addColumn('number', masterLocation.LOCAL_ID);
   });

   for (var i = 0; i < 13; i++) {
      var arr = [i];
      ms2.forEach(function(masterLocation, index) {
         arr.push(masterLocation['Class' + i]);
      });

      data.addRow(arr);
   }

   return data;
}

function getRandomData(base) {
   var data = new google.visualization.DataTable();
   data.addColumn('number', 'Class');
   data.addColumn('number', ms2[0].LOCAL_ID);
   data.addColumn('number', ms2[1].LOCAL_ID);
   data.addColumn('number', ms2[2].LOCAL_ID);


   // add random data
   var y1 = base,
      y2 = base,
      y3 = base;
   for (var i = 0; i < 13; i++) {
      y1 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
      y2 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
      y3 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
      data.addRow([i, y1, y2, y3]);
   }

   return data;
}

function init() {
   data = [];
   data[0] = getData();
   data[1] = getRandomData(1000);
   chart = new google.charts.Line(document.getElementById('chart_div'));

   options = {
      chart: {
         title: 'Box Office Earnings in First Two Weeks of Opening',
         subtitle: 'in millions of dollars (USD)'
      },
      width: 500,
      height: 300,
      vAxis: {
         gridlines: {
            color: '#ccc'
         }
      },
      hAxis: {
         gridlines: {
            color: '#ccc'
         }
      },
      animation: {
         duration: 1000,
         easing: 'out'
      }
   };

   drawChart();
}


function drawChart() {
   var columns = [];
   var defaultSeries = [1, 2, 3];
   var series = {};
   for (var i = 0; i < data[current].getNumberOfColumns(); i++) {
      if (i === 0 || defaultSeries.indexOf(i) > -1) {
         // if the column is the domain column or in the default list, display the series
         columns.push(i);
      } else {
         // otherwise, hide it
         columns.push({
            label: data.getColumnLabel(i),
            type: data.getColumnType(i),
            sourceColumn: i,
            calc: function() {
               return null;
            }
         });
      }
      if (i > 0) {
         columns.push({
            calc: 'stringify',
            sourceColumn: i,
            type: 'string',
            role: 'annotation'
         });
         // set the default series option
         series[i - 1] = {};
         if (defaultSeries.indexOf(i) == -1) {
            // backup the default color (if set)
            if (typeof(series[i - 1].color) !== 'undefined') {
               series[i - 1].backupColor = series[i - 1].color;
            }
            series[i - 1].color = '#CCCCCC';
         }
      }
   }

   options['series'] = series;


   function showHideSeries() {
      var sel = chart.getSelection();
      if (sel.length < 1 || sel[0].row) {
         return;
      }

      var col = sel[0].column;
      if (typeof(columns[col]) == 'number') {
         var src = columns[col];


         var calcFunc = null;
         if (document.getElementById("removeSeriesOnSelect").checked) {
            calcFunc = function() {
               return null;
            };
         }

         columns[col] = {
            label: data[current].getColumnLabel(src),
            type: data[current].getColumnType(src),
            sourceColumn: src,
            calc: calcFunc
         };
         // grey out the legend entry
         series[src - 1].color = '#CCCCCC';
      } else {
         var src = columns[col].sourceColumn;
         // show the data series
         columns[col] = src;
         series[src - 1].color = null;
      }
      var view = new google.visualization.DataView(data[current]);
      view.setColumns(columns);

      chart.draw(view, options);
   }


   google.visualization.events.addListener(chart, 'select', showHideSeries);

   google.visualization.events.addListener(chart, 'ready', function() {
      button.disabled = false;
   });

   var view = new google.visualization.DataView(data[current]);
   view.setColumns(columns);
   chart.draw(view, options);
}

这里是 jsFiddle:https://jsfiddle.net/sp7atw1L/

编辑:我开始了赏金。给定全局变量,也许是间接的做事方式。我不反对完成同样事情的直接重构/重做。

【问题讨论】:

    标签: javascript charts google-visualization


    【解决方案1】:

    确实,该错误与注释列有关。在drawChart() 之后,您的列数组是[0,1,{a},2,{a},3,{a}]

    > when column 1 clicked, everything is ok. 
    > when column 2 clicked, columns[2] is {a}, which in your code is replaced by 1, so, you get another copy of column 1
    > when column 3 clicked, columns[3] is 2, so, the wrong row is selected
    

    这些都是后果,但问题在于chart.getSelection() 没有考虑注释列并返回错误的索引。我不确定为什么会发生这种情况,但是如果您在这样的 onclick 处理程序中绘制 DataView(而不是 DataTable)

     //chart.draw(data[current], options);   <-------remove this
    
     var view = new google.visualization.DataView(data[current]);
     view.setColumns(columns);// <---make columns global
     chart.draw(view, options);
    

    它解决了这个问题。一个与注释相关的问题是例如here


    另外,在getData()这一行

    arr.push(masterLocation['Class' + i]);
    

    应该是

    arr.push(masterLocation['Class' + i+1]);
    

    【讨论】:

      猜你喜欢
      • 2020-01-31
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 2013-09-17
      • 1970-01-01
      相关资源
      最近更新 更多