将不同大小的数据集动态添加到 Google 可视化图表

Dynamically add different sized data sets to Google Visulation Chart

我使用 simpleXML 遍历数据。我正在寻找一种灵活的方法来循环数据以绘制 Google 图表。请记住,Google 图表的列数在任何阶段都会有所不同。

下面是我试图在图表上绘制的数据示例。

<dealers>
  <dealer>
    <dealer>Sydney</dealer>
    <sales>265</sales>
    <year>2015 FY</year>
  </dealer>
  <dealer>
    <dealer>Sydney</dealer>
    <sales>218</sales>
    <year>2016 FY</year>
  </dealer>
  <dealer>
    <dealer>Melbourne</dealer>
    <sales>143</sales>
    <year>2016 FY</year>
  </dealer>
  <dealer>
    <dealer>Brisbane</dealer>
    <sales>181</sales>
    <year>2016 FY</year>
  </dealer>
</dealers>

我如何遍历它来生成下面的图表?

var data = google.visualization.arrayToDataTable([
                  ['Year', 'Sydney', 'Melbourne', 'Brisbane'],
                  ['2015 FY', 265, 0, 0],
                  ['2016 FY', 218, 143, 181]
                ]);

请记住,将来我们可能会有一个新经销商,因此循环需要足够灵活以将新经销商添加为一列,并相应地将值添加到行中的正确位置。同样如上面的示例数据所示,如果没有为该年份指定值,则需要向该行添加 0。

这是我用来为 google.visualization.arrayToDataTable 构建数组的函数。它需要一个 two-dimensional 数组,您可以为每一列 heading/value.

使用内在值或文字 objects

第一部分构建列标题。使用 object,您可以为 idlabeltype 赋值。 maybe others...

对于列值,object 有两个键:v(值)和 f(格式化值)。

  var data = new google.visualization.arrayToDataTable(GetXmlDataArray(xmlObj), false);

  function GetXmlDataArray(sender, args) {
    var colArray;  // column heading array
    var colHdr;    // column heading
    var colValue;  // column value
    var gglArray;  // array to be returned
    var rowArray;  // data row array
    var nlItems;   // xml columns
    var nlRows;    // xml rows

    // init return array and column heading array
    gglArray = [];
    colArray = [];

    // get columns heading xml nodes
    nlItems = sender.get_xml().selectNodes('//cog:item');

    // build column headings
    for (var i = 0; i < nlItems.length; i++) {
      // column literal
      colHdr = {};
      colHdr.id = 'column_' + i;
      colHdr.label = nlItems[i].getAttribute('name');

      // check data type
      switch(nlItems[i].getAttribute('type')) {
        case 'xs:double':
          colHdr.type = 'number';
          break;

        case 'xs:dateTime':
          colHdr.type = 'datetime';
          break;

        default:
          colHdr.type = 'string';
      }

      // add column
      colArray.push(colHdr);
    }

    // add column headings to return array
    gglArray.push(colArray);

    // get column value xml nodes
    nlRows = sender.get_xml().selectNodes('//cog:row');

    // build data rows
    for (var i = 0; i < nlRows.length; i++) {
      // init row array
      rowArray = [];

      // process each column
      for (var x = 0; x < nlRows[i].childNodes.length; x++) {
        // check if column is null
        if (nlRows[i].childNodes[x].getAttribute('xs:nil')) {
          colValue = null;
        } else {
          // set the text value, depends on the browser
          colValue = nlRows[i].childNodes[x].text || nlRows[i].childNodes[x].textContent;
        }

        // check the data type
        switch(colArray[x].type) {
          // format date columns
          case 'datetime':
            // ensure there is a value
            if (colValue) {
              // set date value
              colValue = new Date(colValue);

              // add column value to row array
              rowArray.push({
                v: colValue,                  // column value
                f: colValue.toLocaleString()  // column formatted value
              });
            } else {
              rowArray.push(colValue);
            }
            break;

          default:
            // add column value to row array, no object needed
            rowArray.push(colValue);
        }
      }

      // add column values to return array
      gglArray.push(rowArray);
    }

    return gglArray;
  }

我正在使用的 XML 看起来与此类似...

<dataset>
    <metadata>
          <item name="Site" type="xs:string" length="18"/>
          <item name="ID" type="xs:double" precision="2"/>
    </metadata>
    <data>
        <row>
            <value>ABC</value>
            <value>4886</value>
        </row>
        <row>
            <value>DEF</value>
            <value>4667</value>
        </row>
        <row>
            <value>GHI</value>
            <value>2892</value>
        </row>
        ...
    </data>
</dataset>