jma*_*mac 10 javascript google-visualization google-data-api google-datatable
使用Google的Visualization API,我使用google.visualization.data.group根据我的原始数据创建子表.我的原始数据使用{v:"US",f:"United States"}的技巧来显示除值之外的其他内容,但是当我使用聚合函数时,格式化被消除,只留下"US"部分.
有没有办法保留原始格式,或者将其添加回使用组聚合创建的DataTables的简单方法?
样本数据:
[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],
Run Code Online (Sandbox Code Playgroud)
聚合功能:
var countryData = google.visualization.data.group(
rawData,
[0, 1],
[{'column': 4, 'aggregation': google.visualization.data.sum, 'type': 'number'}]
);
Run Code Online (Sandbox Code Playgroud)
编辑:
进一步考虑,可能无法对格式进行分组,因为无法保证每个值的格式都是一致的.考虑到这一点,编写一个将格式添加到我的数据的每一列的函数可能更好(或唯一可能).所以问题就变成了,"我该怎么做?"
我真的不想单独创建原始数据作为未格式化的值,然后使用其他表来查找每个值的格式.这将需要额外的2个表(一个用于28行的区域,一个用于超过240行的国家),然后创建两个函数来查看分组表中的每个值(将有30年以上的数据,意味着成千上万行)添加值.
这似乎是一个非常复杂的解决方案.
有没有办法用修饰函数做到这一点?我可以编写一个函数来将表中的每个值作为{v:"US",f:"United States"}格式化对象返回吗?或者是否有一种简单的方法来编写列格式化程序,它将在我的原始表中查找适当的值并采用该格式?这对我(谁必须写它)和用户(谁必须加载它)都会造成最少的麻烦?
编辑2:
看起来我应该能够使用以下内容为新表创建格式化程序:
function (dt, row) {
return {
v: (dt.getValue(row, 1) / 1000000),
f: (dt.getValue(row, 1) / 1000000) + 'M'
}
}
Run Code Online (Sandbox Code Playgroud)
但问题在于,由于我没有处理数字格式,我必须创建某种查找表来获取值,在查找表中查找,然后返回适当的格式.看起来我可能需要逐行遍历整个表,这是几千行.
我无法想象没有一些强力循环和分配值就没有一种简单的方法可以做到这一点.
编辑3:
所以我尝试了一些棘手的事情.我没有将每一行设置为值/格式,而是将值/格式部分创建为字符串,然后在分组后使用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],
Run Code Online (Sandbox Code Playgroud)
这是新代码:
var countryCount = countryData.getColumnRange(0).count;
for (var i = 0; i <= countryCount; i++) {
countryData.setValue(i, 1, eval('(' + countryData.getValue(i,1) + ')'));
};
Run Code Online (Sandbox Code Playgroud)
问题在于,当我将其输出到Google DataTable时,它会显示{v:'AE',f:'阿拉伯联合酋长国'},尽管使用eval正确检查结果可以让我:
>>> eval('(' + countryData.getValue(i,1) + ')')
Object v="AE" f="United Arab Emirates"
Run Code Online (Sandbox Code Playgroud)
那么我在这里做错了什么?
我自己刚刚遇到这个问题。我决定使用修饰符将值更改为格式化值,使用原始数据表查找格式化值。这不是非常有效,但它有效并且计算机速度很快。
首先创建一个查找函数:
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;
}
Run Code Online (Sandbox Code Playgroud)
然后在修改器中调用它,更改原来的组调用:
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'}]
);
Run Code Online (Sandbox Code Playgroud)
更新:看来您需要保留该值和格式化值。在显示饼图的情况下,我不关心保留原始值。我想这对你不起作用,但我会在这里为其他可能有像我这样更简单的情况的人留下这个答案。
我又花了几分钟的时间,这里有一个替代方案,它将复制格式化的值,同时保留原始的单元格值。
创建一个使用查找函数的复制函数:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,根据您的情况,为要复制的每个列调用一次。
copyFormattedValues(rawData, 0, countryData, 0);
copyFormattedValues(rawData, 1, countryData, 1);
Run Code Online (Sandbox Code Playgroud)
您的源列和目标列相同,但在某些情况下它们可能不同。
当然,理想情况下所有这一切都会自动发生。