1

Der folgende Code sollte ein DataView aus einer CSV-Datei auffüllen. Das DataView wird dann einem DashBoard zugeführt, das ein LineChart und einen ChartRangeFilter umfasst, die miteinander verbunden sind. Mein Problem ist, dass, während der ChartRangeFilter eine korrekte Chart-Vorschau zeigt und ich den Bereich auswählen kann, der LineChart nur einen leeren Datensatz zeigt, aber mit dem richtigen Datentyp und den Achsenbeschriftungen. Ich gehe davon aus, dass der DataView-Inhalt in Ordnung ist, da der ChartRangeFilter ihn anzeigen kann. Warum kann der LineChart das nicht auch tun? DieseWarum wird DataView-Inhalt mit Google Visualization in ChartRangeFilter angezeigt, aber nicht in dem zugehörigen LineChart?

google.load('visualization', '1', {packages: ['controls', 'charteditor']}); 
google.setOnLoadCallback(drawChart); 

function drawChart() { 
    // Create CSV string 
    csvString = 'TIME,TEMP0,HUM0\n13:00:04,24.7,50\n13:01:05,26.7,60\n13:02:04,22.7,52\n13:03:05,14.7,40\n13:04:04,34.7,80\n13:05:05,24.7,50'; 

    // Parse string into an Array 
    var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}); 

    // Convert Array into a DataTable 
    var data = new google.visualization.arrayToDataTable(arrayData); 

    // Create DataView from DataTable 
    var view = new google.visualization.DataView(data); 

    // Convert string times in first column to timeofday (thanks to WhiteHat!) 
    var columns = []; 
    for (var i = 0; i < data.getNumberOfColumns(); i++) { 
     columns.push(i); 
    } 

    columns[0] = { 
     calc: function(dt, row) { 
      var thisDate = new Date('1/1/2016 ' + dt.getValue(row, 0)); 
      return [thisDate.getHours(), thisDate.getMinutes(), thisDate.getSeconds(), thisDate.getMilliseconds()]; 
     }, 
     label: arrayData[0][0], 
     type: 'timeofday' 
    }; 

    // Determine which columns should be visible 
    view.setColumns(columns);  

    // Create Dashboard 
    var dash = new google.visualization.Dashboard(document.getElementById('dashboard')); 

    // Range filter control wrapper 
    var control = new google.visualization.ControlWrapper({ 
     controlType: 'ChartRangeFilter', 
     containerId: 'control_div', 
     options: { 
      filterColumnIndex: 0, 
      ui: { 
       chartOptions: { 
        height: 50, 
        width: 1000, 
       }, 
       chartView: { 
        columns: [0, 1,2] 
       } 
      } 
     } 
    }); 

    // Line chart wrapper 
    var chart = new google.visualization.ChartWrapper({ 
     chartType: 'LineChart', 
     containerId: 'chart_div', 
     dataTable: view, 
     options:{ 
      title: 'Home Automation - Environment Sensor Log', 
      width: 1000, 
      height: 400 
     } 
    }); 

    // Bind control and chart in Dashboard 
    dash.bind([control], [chart]); 

    // Draw dashboard using Dataview as source 
    dash.draw(view); 
} 

ist das aktuelle Ergebnis:

LineChart not showing DataView content while ChartRangeFilter does

Dank!

Antwort

1

versucht, eine Reihe von Dingen, die Grafik mit 'timeofday' zur Arbeit zu kommen, aber kein Glück

jedoch eine 'date' Spalte, formatiert als 'HH:mm:ss' mit scheint Arbeits Snippet folgende feinen

sehen zu arbeiten.

Änderungen sind:

1) als Zeit formatiert loader.js vs. jsapi
2) geändert calc Funktion zurückzukehren Datum mit
3) hinzugefügt hAxis.ticks sowohl chart und control
4) verwendet getColumnRange einzustellen die vAxis.viewWindow auf der chart

google.charts.load('current', { 
 
    callback: function() { 
 
    // Create CSV string 
 
    csvString = 'TIME,TEMP0,HUM0\n13:00:04,24.7,50\n13:01:05,26.7,60\n13:02:04,22.7,52\n13:03:05,14.7,40\n13:04:04,34.7,80\n13:05:05,24.7,50'; 
 

 
    // Parse string into an Array 
 
    var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}); 
 

 
    // Convert Array into a DataTable 
 
    var data = new google.visualization.arrayToDataTable(arrayData); 
 

 
    // Create DataView from DataTable 
 
    var view = new google.visualization.DataView(data); 
 

 
    // Convert string times in first column to timeofday (thanks to WhiteHat!) 
 
    var columns = []; 
 
    for (var i = 0; i < data.getNumberOfColumns(); i++) { 
 
     columns.push(i); 
 
    } 
 

 
    var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'}); 
 
    columns[0] = { 
 
     calc: function(dt, row) { 
 
      var dateValue = new Date('1/1/2016 ' + dt.getValue(row, 0)); 
 
      return { 
 
       v: dateValue, 
 
       f: formatter.formatValue(dateValue) 
 
      }; 
 
     }, 
 
     label: arrayData[0][0], 
 
     type: 'date' 
 
    }; 
 

 
    // Determine which columns should be visible 
 
    view.setColumns(columns); 
 

 
    var tickMarks = []; 
 
    for (var i = 0; i < view.getNumberOfRows(); i++) { 
 
     tickMarks.push(view.getValue(i, 0)); 
 
    } 
 

 
    // Create Dashboard 
 
    var dash = new google.visualization.Dashboard(document.getElementById('dashboard')); 
 

 
    // Get column range min & max 
 
    var yRange1 = view.getColumnRange(1); 
 
    var yRange2 = view.getColumnRange(2); 
 

 
    var control = new google.visualization.ControlWrapper({ 
 
     controlType: 'ChartRangeFilter', 
 
     containerId: 'control_div', 
 
     options: { 
 
      filterColumnIndex: 0, 
 
      ui: { 
 
       chartOptions: { 
 
        height: 50, 
 
        width: 1000, 
 
        hAxis: { 
 
         ticks: tickMarks, 
 
         format: 'HH:mm:ss' 
 
        } 
 
       } 
 
      } 
 
     } 
 
    }); 
 

 
    // Line chart wrapper 
 
    var chart = new google.visualization.ChartWrapper({ 
 
     chartType: 'LineChart', 
 
     containerId: 'chart_div', 
 
     options:{ 
 
      pointSize: 8, 
 
      title: 'Home Automation - Environment Sensor Log', 
 
      width: 1000, 
 
      height: 400, 
 
      hAxis: { 
 
       ticks: tickMarks, 
 
       format: 'HH:mm:ss' 
 
      }, 
 
      vAxis: { 
 
       viewWindow: { 
 
       min: Math.min(yRange1.min, yRange2.min), 
 
       max: Math.max(yRange1.max, yRange2.max) 
 
       } 
 
      } 
 
     } 
 
    }); 
 

 
    // Bind control and chart in Dashboard 
 
    dash.bind(control, chart); 
 

 
    // Draw dashboard using Dataview as source 
 
    dash.draw(view); 
 
    }, 
 
    packages: ['controls', 'corechart'] 
 
});
<script src="https://www.gstatic.com/charts/loader.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script> 
 
<div id="dashboard"> 
 
    <div id="chart_div"></div> 
 
    <div id="control_div"></div> 
 
</div>

+0

Entschuldigung für die Verzögerung! Ja, es funktioniert, aber es ist sehr langsam neu zu zeichnen, wenn ich den tatsächlichen Datensatz verwende, der aus einer CSV-Datei importiert wurde, die viel größer ist (1400+ Zeilen x 30 Spalten). Ich muss einige Tests durchführen, um zu sehen, was das verursacht. Ich vermute, dass die getColumnRange das vAxis.viewWindow oder die zahlreichen Ticks jedes Mal neu gezeichnet wird, wenn ich die Range Filter Trackbars verschiebe. Auch kann ich die Spalten, die ich sehen möchte, nicht mehr mit 'view.setColumns ([0,1,5,9,13,17,21,25,29]);' wie zuvor festlegen. Als ich bekomme ich die Fehlermeldung "Der Filter kann nicht auf eine Spalte des Typs Zeichenfolge" Fehlermeldung erneut ... – tohox

+0

Ich denke, das ist der Grund, warum die obige Antwort verwendet eine berechnete Spalte anstelle von "0" - wie für langsam , das ist die Art der clientseitigen Verarbeitung, mehr Daten erfordern mehr Zeit ... – WhiteHat

+0

War in der Lage, die Dinge wesentlich zu beschleunigen, indem die 'vAxis'' viewWindow'-Größenänderung und die zugehörige 'view.getColumnRange' entfernt wurden. Ich habe auch die Punkte im Liniendiagramm losgeworden, da ihre Dichte zu hoch war, um den Rest abzudecken. Jetzt muss ich nur noch eine Möglichkeit finden, welche Spalten ich aus dem ursprünglichen CSV-Datensatz sehen möchte. Danke, WhiteHat! – tohox