如何在dc.js中绘制帕累托图

时间:2019-12-07 08:36:19

标签: dc.js crossfilter

我正在尝试使用dc.js中的复合图来实现帕累托图。如果输入的数据是线性的而不是有序的,则复合排序效果很好。我被困在实现以下目标上。

我有以下代码,在此过程中,我试图创建在x轴上放置原因并有两个y轴的pareto。一个代表时间的总和,另一个代表时间贡献的总百分比

  

total_time =总和(时间)

     

贡献=时间/总时间

假设一张图表按ASC顺序以时间值排序,而另一张图表按DESC顺序按贡献

这里的方法是什么?

import "package:flutter/material.dart";
import "dart:async";

class JoinScreen extends StatefulWidget {
@override
 _JoinScreenState createState() {   
    return _JoinScreenState();
    }
 }

class _JoinScreenState extends State<JoinScreen> 
 with SingleTickerProviderStateMixin {
  List<Widget> widgetList = [];

  @override
  void initState() {
    new Timer(const Duration(milliseconds: 100), () {
    print('timeout');
    setState(() {        
    widgetList.add(secondHalf());
   });
  });

  new Timer(const Duration(milliseconds: 1000), () {
    print('timeout');
    setState(() {        
      widgetList.add(firstHalf());
    });
  });

  super.initState();
 }

 @override
 Widget build(BuildContext context) {
   return AnimatedSize(
     vsync: this,
     duration: Duration(seconds: 2),
     child: Column(
       children: widgetList,
       ),
   );
 }

 Widget firstHalf() {
   return Expanded(
     child: Container(
       decoration: BoxDecoration(color: Colors.blueAccent),
     ),
   );
 }

 Widget secondHalf() {
   return Expanded(
     child: Container(
       decoration: BoxDecoration(color: Colors.pinkAccent),
     ),
    );
  }
}

PS:我在此链接here上也有一个设置

1 个答案:

答案 0 :(得分:1)

所以我们需要一个小组来计算每个类别的总时间(“原因”),对计算每个项目的贡献进行排序,并累积折线图的贡献。

我们可以将此逻辑放入fake group中,该逻辑可以一次计算所有内容:

function pareto_group(group, groupall) { // 1
    return {
      all: function() { // 2
        var total = groupall.value(), // 3
            cumulate = 0; // 4
        return group.all().slice(0) // 5
          .sort((a,b) => d3.descending(a.value, b.value)) // 6
          .map(({key,value}) => ({ // 7
            key,
            value: {
              value,
              contribution: value/total,
              cumulative: (cumulate += value/total)
            }
          }))
      }
    };
}
var pg = pareto_group(grp1_, allTime_);   
  1. 我们需要一个普通组和一个全部组作为输入
  2. “假组”是实现.all()并返回{key, value}对数组的对象
  3. 我们需要所有类别的当前总计,以便计算每个类别的贡献
  4. 从左到右,我们将不断积累贡献
  5. 我们将使用原始组的.all(),并使用.slice(0)复制数组
  6. 按值降序排列
  7. ...并使用相同的键生成一个新数组,但其值会随着个人贡献和累积贡献而增加​​

初始化图表需要一些晦涩的解决方法。除了要说的是,这比您想象的要复杂得多,我不会对此做得更深入。

chart
 .width(768)
        .height(480)
        .x(d3.scaleBand())
        .elasticX(true)
        .xUnits(dc.units.ordinal)
        .group(pg)
        ._rangeBandPadding(1)
        .yAxisLabel("The Y Axis")
        .legend(dc.legend().x(80).y(20).itemHeight(13).gap(5))
        .renderHorizontalGridLines(true)
        .compose([
            dc.barChart(chart)
                .dimension(dim_)
                .barPadding(1)
                .gap(1)
                .centerBar(true)
                .clipPadding(10)
                .group(pg, "Contribution", kv => kv.value.value),
            dc.lineChart(chart) 
                .dimension(dim_)
                .colors('red')
                .group(pg, "Cumulative", kv => Math.floor(kv.value.cumulative*100))
                .useRightYAxis(true)
                .dashStyle([2,2])
            ])
        .brushOn(false);

 chart.rightYAxis().tickFormat(d => d + '%')  

请注意,我们正在启用elasticX,以使图表重新读取每次重绘的X比例域。

Most of the special cases involve ordinal charts

这是屏幕截图:

pareto chart

还有here is a demo fiddle