需要在饼图中包含一个负数组。

问题描述 投票:1回答:1

我现在已经有了几张不错的图表,但在这里我可能已经咬的比我能嚼的还多。我知道你通常不会考虑涉及负数分组的PieChart,但请耐心听我说。

我有一列值,我想在PieChart中显示。

PieChart应该有2个元素,1.正数的平均值2.负数的平均值。负数的平均值

饼片的文本元素应注意1.正平均值£? (?%)2. 负数平均值£? (?%)

我不能完全掌握的是PieChart如何处理负值。我的饼图没有负值元素的分片。所以想来想去,我能不能只在负数上加入一个-1的乘数。

我在想,把正数和负数分别提取到不同的数组中,用miltiplier调整负数数组,然后再把这两个数组重新纳入到我的饼图中,会不会提供一个合理的解决方案?如果不是太繁琐的话,我希望能在这里得到一些流程上的指导。

我只是期望,比如平均负值说20,平均正值60.而百分比显示为25%和75%。我感兴趣的是这两个数字之间的关系。

以上是我仅仅使用总值的情况。我还需要一些帮助,如何提取和使用平均值。

<div id="paybacksplit"></div>

<pre id="data">
Trade,Payback
1,85
2,74
3,-90
4,77
5,93
6,85
7,95
8,98
9,98
10,-88
11,10
12,98
13,93
14,65
15,76
16,81
17,0
18,0
19,96
20,-9
21,96
22,94
23,96
24,94
25,-88
26,8
27,85
28,88
29,90
</pre>
var pbschart = new dc.PieChart("#paybacksplit");

var trades = d3.csvParse(d3.select('pre#data').text());
  trades.forEach(function(x) {
    x.Payback = +x.Payback;
  });

var ndx           = crossfilter(trades),

   tradeDimension    = ndx.dimension(function(d) {
                            if (d.Payback >= 0)
                            return "Profitable";
                            else
                            return "Losing";
                            });
   paybackSumGroup = tradeDimension.group().reduceSum(function(d) {return d.Payback;});


   pbschart
    .width(768)
    .height(480)
    .slicesCap(2)
    .innerRadius(2)
    .dimension(tradeDimension)
    .group(paybackSumGroup)
    .legend(dc.legend().highlightSelected(true))
    .on('pretransition', function(chart) {
        chart.selectAll('text.pie-slice').text(function(d) {
            return d.data.key + '  £ '+ d.data.value + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
        })
    });

   pbschart.render();

jsfiddle是 此处

接下来发生了什么。

Gordons的答复帮了大忙,但我还没有熟练到足以弄清下一阶段的工作,即返回平均值。

然而,由于数据来自于我自己的数据,我只是重组了输出,为每个项目提供一列ProfitLoss,第二列提供数值(负值转换为正值)。

以我有限的dc.js知识,重新调整我的数据库输出是比较容易的,我最后得到的是

<div id="paybacksplit2"></div>
<!-- here's a way to load data from a jsfiddle, to avoid CORS
  problems - see http://stackoverflow.com/a/22896088/676195
  -->
<pre id="data">
Trade,Payback
Prof,85
Prof,74
Loss,90
Prof,77
Prof,93
Prof,85
Prof,95
Prof,98
Prof,98
Loss,88
Prof,10
Prof,98
Prof,93
Prof,65
Prof,76
Prof,81
Prof,0
Prof,0
Prof,96
Loss,9
Prof,96
Prof,94
Prof,96
Prof,94
Loss,88
Prof,8
Prof,85
Prof,88
Prof,90
</pre>

var pbschart2 = new dc.PieChart("#paybacksplit2");

var numberFormat = d3.format("(.2f");

var trades = d3.csvParse(d3.select('pre#data').text());
  trades.forEach(function(x) {
    x.payback = +x.Payback
    x.trade = x.Trade 
    ;
  });

var ndx           = crossfilter(trades),

   tradeDimension    = ndx.dimension(function(d) {return d.trade;});
   paybackSumGroup = tradeDimension.group().reduceSum(function(d) {return d.payback;});

var nameDim = ndx.dimension(function(d) { return d.trade; })
var totalValGroup = nameDim.group().reduce(reduceAddVal, reduceRemoveVal, reduceInitialVal);           

 var result = totalValGroup.top(Infinity);
            console.log(result);

            function reduceAddVal(p, v) {
                ++p.count;
                p.totalVal += v.payback;  
                p.average = p.totalVal / p.count;                                      
                return p;
            }

            function reduceRemoveVal(p, v) {
                --p.count;
                p.totalVal -= v.payback;  
                p.average = p.totalVal / p.count;                                      
                return p;
            }

        function reduceInitialVal() {
            return {
                count: 0,
                totalVal: 0,
                average: 0
            };
        }

 pbschart2
    .width(768)
    .height(200)
    .slicesCap(2)
    .dimension(nameDim)
    .group(totalValGroup)
    .valueAccessor(function (p) {
        return p.value.average;
        })
    .legend(dc.legend().highlightSelected(true))
   .on('pretransition', function(chart) {
        chart.selectAll('text.pie-slice').text(function(d) {
            return '  £ '+ numberFormat(d.data.value.average);
        })
    });   


   pbschart2.render();

这给了我以下的结果。

Average Trade Value

这差不多就是我想要的东西。

更新的小提琴 此处

也许以后我可以在dc.js中做更多的事情,但由于我可以选择定义自己的数据提取,这对我来说是目前最简单的选择。

谢谢Gordon,我正在一点一点的进步。

dc.js crossfilter
1个回答
1
投票

在dc.js中,有很多不同的 "accessors",它们允许你提供一个函数,它可以

  • 告诉图表如何检索一些数据。
  • 也可以对数据进行预计算。

在这种情况下 valueAccessor 是有帮助的。

pbschart
  .valueAccessor(kv => Math.abs(kv.value))

negative slice snapshot

叉你的小提琴.

© www.soinside.com 2019 - 2024. All rights reserved.