2016-04-06 4 views
3

Schalt ich einige Beispiele gezwickt habe ich über das Netz gefunden, die mir erlauben zu entfernen/greyout eine Reihe, wenn es angeklickt wird (Legende oder Linie selbst).Google Charts und Datentabellen Kantengraph Aufrechterhaltung Zustand

Ich wollte dann Fähigkeit, zwischen Datentabellen zu wechseln hinzuzufügen und haben, was/greyedout auf die neue Datentabelle zu übertragen verborgen war.

nahm ich die Idee von Schaltdaten von https://developers.google.com/chart/interactive/docs/animation#value-changes

Mein Problem ist, ich sehr seltsam Ergebnisse, wenn auf dem „Switch“ klicken und Schaltdatentabellen (meine Graphen sind nicht richtig wie das Beispiel Animieren), manchmal es wird die richtige Auswahl beibehalten, aber wenn Sie auf eine andere Serie klicken, erscheint eine magische oder es wird eine andere Serie als die angeklickte entfernen. Ich kann es nicht herausfinden, so dass beide Databases dieselbe Auswahl beibehalten (Auswahl bedeutet ausgegraute/entfernte Serie).

Es ist erwähnenswert, dass

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

versteckte Spalten aide für die Serie in einem zusätzlichen Logik erweitert. Während ich es momentan nicht direkt verwende, möchte ich, dass es bleibt und richtig funktioniert, weil ich denke, dass ich es in Zukunft verwenden werde. Diese "versteckten" Spalten fügen Komplexität hinzu, wo ich denke, dass der Fehler lebt.

Der Code ist hier: https://jsfiddle.net/sp7atw1L/

Edit::

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); 
} 

Hier die jsFiddle ist ich eine Prämie gestartet. Angesichts der globalen Variablen und vielleicht der indirekten Art und Weise, dies zu tun. Ich bin nicht gegen einen direkten Refactor/Redo, der dasselbe bewirkt.

Antwort

0

In der Tat bezieht sich der Fehler auf Annotationsspalten. Nach drawChart() ist Ihr Spalten-Array [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 

Dies sind Folgen, aber das Problem liegt in chart.getSelection() nicht Konto Anmerkung Spalten nehmen in und falsche Indizes zurück. Ich bin nicht sicher, warum dies geschieht, aber wenn Sie Dataview ziehen (anstelle von Datatable) in Onclick-Handler wie diese

//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); 

löst es das Problem. Ein damit zusammenhängendes Problem mit Anmerkungen ist z.B. here


, zusätzlich in getData() die Linie

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

sollte

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