在d3中从系列创建系列 [英] Creating series from series in d3

查看:145
本文介绍了在d3中从系列创建系列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个表单的数据(简化,但在管理和挖掘之间假设有20列):

I have data of this form (simplified, but assume 20 columns between Admin and Mining):

Date,Series,Admin,Mining,CPI
1990,Ordinary Time Earnings,20,30,96
1991,Ordinary Time Earnings,22,33,100
1990,Total Earnings,25,38,96
1991,Total Earnings,29,43,100

我将这样分成两个系列: p>

Which I separate out into two series like this:

d3.csv("avgearnings_v1_1.csv", function(error, data) {
  if (error) throw error;
  OrdinaryTimeEarnings = data
    .filter(function(d) {
        if(d.Series == 'Ordinary Time Earnings')
            return d;
    });
  TotalEarnings = data
    .filter(function(d) {
        if(d.Series == "Total Earnings")
            return d;
    });

并且可以让它在图上显示没有任何问题。更多系列:

And can get that to display on a graph without any issue. What I want to do next is create two more series:

OrdinaryTimeEarningsReal = OrdinaryTimeEarnings;
TotalEarningsReal = TotalEarnings;

然后重新计算这些新系列。基本上:

And then recalculate those new series. Basically:


  • 对于不是Date / Series / CPI的任何列


  • 将每个Mining-Admin列按照CPI分别乘以100.

  • 因此:新值= Value] / [CPI])* 100

  • For any column that is not Date/Series/CPI
  • Take the CPI value for that year
  • Individually divide each of the Mining-Admin columns by the CPI and multiply by 100.
  • So: New Value = ([Old Value]/[CPI])*100

我的代码很可怕,但我可以使用以下命令获得正确的值:

My code is terrible but I can get the correct values using this:

OrdinaryTimeEarningsReal
    .forEach(function (z,i) {
        var CPI = z["CPI"];
        d3.map(z, function(b) {return b;})
            .forEach(function (c) {
                if(c !== "Date" && c !== "Series" && c !== "CPI" ) 
                    OrdinaryTimeEarningsReal[i][c] = ((z[c])/(CPI))*100;       
            });
    });

但是,当我这样做时,它也会更新原来的OrdinaryTimeEarnings系列,其他和OrdinaryTimeEarnings中的原始数据丢失。

But, when I do this it is somehow also updating the original OrdinaryTimeEarnings series, such that they equal each other and the original data in OrdinaryTimeEarnings is lost.

我不确定这是我使用裸对象的事实(当在它内部迭代,eek!)或上面的代码实际上改变值在原始数据对象(和我创建的所有4系列之后,只是它的引用)。

I'm not sure whether it's the fact I'm using the bare object (while iterating within it, eek!) or that the code above is actually changing the values in the original data object (and all 4 of the series I've created after are just references to it).

无论如何,我不能工作!我尝试了一些公正的几种不同的语法形式,但不能解决它。

Either way, I can't work it out! I've tried a fair few different syntax forms but can't work it out. Help would be greatly appreciated to achieve this.

推荐答案

如果你确实使用这个代码来复制你的数组:

If you indeed use this code to "duplicate" your arrays:

OrdinaryTimeEarningsReal = OrdinaryTimeEarnings;
TotalEarningsReal = TotalEarnings;

那么你提到它是正确的,当你说他们引用同一个对象。在JavaScript中,数组是可变的,使用上面的代码,你只需创建两个新的变量,引用内存中的现有数组。

then you mentioned it right, when you said that they reference the same object. In JavaScript, arrays are mutable, and using the code above you just created 2 new variables with a reference to the existing array in the memory.

为了深度克隆使用此方法:

In order to deep clone your array of objects, use this method:

OrdinaryTimeEarningsReal = JSON.parse(JSON.stringify(OrdinaryTimeEarnings));
TotalEarningsReal = JSON.parse(JSON.stringify(TotalEarnings));

这将创建数组的重复,并将它们分配给新的变量,编辑它们,初始数组将不受影响。

This will create duplicates of the array and assign them to the new variables, so that when you'll edit them, the initial arrays will remain unaffected.

现在,关于你的代码,它有点太复杂了。如果我正确理解你想要实现什么,你可以简化它如下:

Now, regarding your code, it's a bit too complex. If I understood correctly what are you trying to achieve, you could simplify it as follows:

OrdinaryTimeEarningsReal
.forEach(function (z,i) {
    for (var c in z) {
        if (z.hasOwnProperty(c) && c !== "Date" && c !== "Series" && c !== "CPI" ) 
            z[c] = z[c] / z.CPI * 100;       
    });
});

祝你好运!

这篇关于在d3中从系列创建系列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆