首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Google图表LineGraph切换数据和维护状态

Google图表LineGraph切换数据和维护状态
EN

Stack Overflow用户
提问于 2016-04-06 05:02:58
回答 1查看 115关注 0票数 3

我调整了一些我在网络上找到的例子,这些例子允许我在点击一个系列(传说或行本身)时删除/删除一个系列。

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

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

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

值得注意的是

代码语言:javascript
复制
         columns.push({
            calc: 'stringify',
            sourceColumn: i,
            type: 'string',
            role: 'annotation'
         });

是在本系列的附加逻辑中添加隐藏列以辅助。虽然我目前没有直接使用它,但我希望它保持正常工作,因为我认为我将在未来使用它。这些“隐藏”列增加了我认为bug存在的地方的复杂性。

守则如下:

代码语言:javascript
复制
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/

编辑:我开始赏金了。考虑到全局变量,或者间接的方式,这是在做事情。我不反对直接重构/重做来完成同样的事情。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-08 19:28:02

实际上,该bug与注释列有关。在drawChart()之后,列数组是[0,1,{a},2,{a},3,{a}]

代码语言:javascript
复制
> 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),就像这样

代码语言:javascript
复制
 //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()中,行

代码语言:javascript
复制
arr.push(masterLocation['Class' + i]);

应该是

代码语言:javascript
复制
arr.push(masterLocation['Class' + i+1]);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36441934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档