9

GoogleのビジュアライゼーションAPIを使用して、私は生データに基づいてサブテーブルを作成するためにgoogle.visualization.data.groupを使用します。私の未処理データは、値以外の値を表示するために{v: "US"、 "f:" United States "}のトリックを使用しますが、集計関数を使用すると、フォーマットが削除され、" US "部分のみが残されます。グーグルビジュアライゼーションAPIでグループ化を使用して書式を保持する

元の書式を保持する方法はありますか、グループ集計を使用して作成したDataTableに簡単に追加する方法はありますか?

サンプルデータ:

[2010, {v:"MA", f:"Morocco"}, {v:"002", f:"Africa"}, {v:"002", f:"Northern Africa"}, 21.12724], 
[2010, {v:"AW", f:"Aruba"}, {v:"019", f:"Americas "}, {v:"019", f:"Caribbean"}, 0.98], 
[2010, {v:"AF", f:"Afghanistan"}, {v:"142", f:"Asia"}, {v:"142", f:"Southern Asia"}, 0.9861], 
[2010, {v:"AO", f:"Angola"}, {v:"002", f:"Africa"}, {v:"002", f:"Middle Africa"}, 5.11774], 

集計関数:

var countryData = google.visualization.data.group(
    rawData, 
    [0, 1], 
    [{'column': 4, 'aggregation': google.visualization.data.sum, 'type': 'number'}] 
); 

編集:保証がないため、さらに思想に

が、それは形式を持つグループに、おそらく不可能ですその形式について各値は一貫しています。これを念頭に置いて、私のデータの各列にフォーマットを追加する関数を書くほうがよいでしょう。だから問題は「どうしたらいいの?」

私は本当にむしろフォーマットされていない値として生データを作成するのではなく、各値のフォーマットを検索するための追加のテーブルを作成します。これには、2つのテーブルが追加されます(1つは28行の領域用、もう1つは240行以上の国用)。次にグループ化されたテーブルの各値を調べる2つの関数を作成します(30年以上のデータ、何千もの行を意味します)。

これは本当に複雑な解決策のようです。

修飾子機能でこれを行う方法はありますか?テーブル内の各値を{v: "US"、f: "United States"}の形式のオブジェクトとして返す関数を記述できますか?または、元のテーブルの適切な値を検索し、その形式を採用する列フォーマッタを書く簡単な方法はありますか?それは私にとって(誰がそれを書かなければならないのか)、そして(それをロードしなければならない)ユーザのために、頭痛を最小限に抑えるだろうか?

EDIT 2:

私はこのようなものを使用して、新しいテーブルのフォーマッタを作成することができるはずのように見えます:

function (dt, row) { 
    return { 
     v: (dt.getValue(row, 1)/1000000), 
     f: (dt.getValue(row, 1)/1000000) + 'M' 
    } 
} 

しかし、問題は、私は数を扱っておりませんので、ということになり私は値を取るルックアップテーブルのいくつかの並べ替えを作成する必要があります、ルックアップテーブルでそれを検索し、適切な形式を返します。また、私はテーブル全体を何千行も繰り返す必要があるかもしれません。

ブルートフォースルーピングと値の割り当てがなければ、これを行う簡単な方法はないとは思いません。

編集3:

だから私はトリッキーなことを試しました。各行を値/フォーマットとして設定するのではなく、value/format部分を文字列として作成し、グループ化してからeval()を使用してオブジェクトを評価しました。これはうまくいった。ここで

[2010, "{v: 'MA', f: 'Morocco'}", 21.13], 
[2010, "{v: 'AW', f: 'Aruba'}", 0.98], 
[2010, "{v: 'AF', f: 'Afghanistan'}", 0.99], 
[2010, "{v: 'AO', f: 'Angola'}", 5.12], 

新しいコードされています:ここにデータがある

var countryCount = countryData.getColumnRange(0).count; 

    for (var i = 0; i <= countryCount; i++) { 
    countryData.setValue(i, 1, eval('(' + countryData.getValue(i,1) + ')')); 
    }; 

の問題は、これはGoogleのデータテーブルに、それは{Vを示したときにI出力: 'AE'、F: 'をアラブ首長国連邦}のevalで結果を確認することは適切に私を与えているという事実にもかかわらず:

>>> eval('(' + countryData.getValue(i,1) + ')') 
Object v="AE" f="United Arab Emirates" 

だから私はここで間違って何をやっていますか?

答えて

1

私はこの問題に直面しました。私は、元のdataTableを使用してフォーマットされた値を見つけるために、修飾子を使用して値をフォーマットされた値に変更することに決めました。これは非常に効率的ではありませんが、動作し、コンピュータは高速です。

var countryData = google.visualization.data.group(
    rawData, 
    [ 
    { 
     'column': 0, 
     'modifier': function(value) { return getFormatForValue(rawData, 0, value); }, 
     'type': 'string' 
    }, 
    { 
     'column': 1, 
     'modifier': function(value) { return getFormatForValue(rawData, 1, value); }, 
     'type': 'string' 
    } 
    ], 
    [{'column': 4, 'aggregation': google.visualization.data.sum, 'type': 'number'}] 
); 

更新:

function getFormatForValue(dataTable, column, value) { 

    // we need to spin through column in the dataTable looking 
    // for the matching value and then return the formatted value 
    var rowcount = dataTable.getNumberOfRows(); 
    for (var i=0; i<rowcount; i++) { 
     if (dataTable.getValue(i, column) === value) { 

      // we found it, this will look much better 
      return dataTable.getFormattedValue(i, column);  
     } 
    } 

    // better than nothing 
    return value; 
} 

は、その後、あなたの元のグループ通話を変更、修飾子のそれを呼び出す:

ファーストルックアップ関数を作成あなたが値と書式設定値を必要とするようです保存された。私の円グラフを表示する場合、私は元の値を保持することに気をつけません。私はこれがあなたのためにはうまくいかないと思うが、私はこのような答えを、私のようなより単純なケースを持つかもしれない他の人のためにここに残す。

これに数分を費やしましたが、ここでは元のセル値を維持したまま書式設定された値をコピーする方法があります。

ルックアップ機能を使用してコピー機能を作成します。

function copyFormattedValues(oldDataTable, oldColumn, newDataTable, newColumn) { 

    var rowcount = newDataTable.getNumberOfRows(); 
    for (var i=0; i<rowcount; i++) { 
     var value = newDataTable.getValue(i, newColumn); 
     var formatted = getFormatForValue(oldDataTable, oldColumn, value); 
     newDataTable.setFormattedValue(i, newColumn, formatted); 
    } 

} 

は、その後、あなたの場合には、コピーしたい列ごとに一回それを呼び出します。

copyFormattedValues(rawData, 0, countryData, 0); 
copyFormattedValues(rawData, 1, countryData, 1); 

ソースと宛先の列は同じですが、場合によっては異なる場合もあります。

もちろん、理想的には、これらすべてが自動的に起こったはずです。

4

わかりました。私はこれを(どれほど厄介なほど複雑であったか)考え出しました。

私は新しいアプローチを試みました。私は自分のデータを再フォーマットし、その文字列内の仕切りに基づいて値/形式を返す関数を作成しました。私は、列1のための分周器の位置を取得するためにこれを使用

[2010, "'MA'|'Morocco'", 21.13], 
[2010, "'AW'|'Aruba'", 0.98], 
[2010, "'AF'|'Afghanistan'", 0.99], 
[2010, "'AO'|'Angola'", 5.12], 

:だから、私のデータは次のようになります

var countryCount = countryData.getNumberOfRows(); 

for (var i = 0; i <= countryCount; i++) { 
    var stringToSplit = countryData.getValue(i,1); 
    var dividerLocation = stringToSplit.indexOf("|"); 
    alert("Divider: " + dividerLocation + ", String: " + stringToSplit); 
    countryData.setValue(i, 1, splitFormat(dividerLocation, stringToSplit)); 
}; 

そして私は、文字列を分割するために、この機能を使用します。

function splitFormat(dividerLocation, stringToSplit) { 
    // alert("entered splitFormat Function"); 
    var stringValue = ""; 
    var formatValue = ""; 
    stringValue = stringToSplit.substring(0, dividerLocation); 
    formatValue = stringToSplit.substring(dividerLocation + 1) 
    alert("v: " + stringValue + ", f: " + formatValue); 
    return { 
     v: stringValue, 
     f: formatValue 
    } 
     } 

私のデータの第1列を 'string'として定義していますが、firebugはsplitFormat()関数から返されたオブジェクトがオブジェクトであることを教えています。そしてf::私はAVと、元のDataTable設定しても

"Error: Type mismatch. Value [object Object] does not match type string in column index 1 (table.I.js,137)" 

問題:コンポーネントをFirebugのは私に次のようOH-SO-有益な助言を与えるとして、それは、返された配列オブジェクトの値を受け入れることを望んでいません{v:、f:}構文を使用してDataTableを定義することはできますが、その列の値が文字列として設定されているため、その構文をテーブルに戻すことはできません。代わりに、私は問題を解決するためのDataTableの「setFormattedValue」プロパティを使用:

function drawVisualization() { 
    var countryTable = new google.visualization.Table(document.getElementById('table')); 

    var countryCount = countryData.getNumberOfRows() - 1; 

    for (var i = 0; i <= countryCount; i++) { 
     var stringToSplit = countryData.getValue(i,1); 
     var dividerLocation = stringToSplit.indexOf("|"); 
     var stringValue = stringToSplit.substring(0, dividerLocation); 
     var stringFormat = stringToSplit.substring(dividerLocation + 1); 
     countryData.setValue(i, 1, stringValue); 
     countryData.setFormattedValue(i, 1, stringFormat); 
    }; 

これは正しく、それは大規模なデータ・セットのビット集約的であっても、私の両方のために適切な値を示しました。もし誰かがこれをやるより簡単な方法を知っていれば、私はそれを聞いて嬉しくなるでしょう。

関連する問題