如何使用dc.js将数据范围放在饼图中?

时间:2017-08-28 05:33:56

标签: dc.js crossfilter

我有一张年龄饼图,目前在数据集中的每个年龄都有饼图。由于年龄范围很宽,因此在饼图中形成了许多薄片。我想把它作为一个范围,比如一个切片应该显示0-18,另一个显示为19-30,依此类推。我怎么能这样做?

这是我的代码

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="bower_components/dcjs/dc.css">
    <link rel="stylesheet" href="bower_components/leaflet/dist/leaflet.css">

    <script src="bower_components/d3/d3.min.js"></script>
    <script src="bower_components/crossfilter2/crossfilter.min.js"></script>
    <script src="bower_components/dcjs/dc.js"></script>

    <!--THE FOLLOWING META IS IMPORTANT, OTHERWISE THERE MIGHT BE A PROBLEM WITH SOME CHARACTERS--> 
    <meta http-equiv="content-type" content="text/html; charset=UTF8"> 
    <!--CDN FOR JQUERY-->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
</head>
<body>
    <div id="map">
        <a class="reset" href="javascript:usChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
        <span class="reset" style="display: none;"> | Current filter: <span class="filter"></span></span>
        <div class="clearfix"></div>
    </div>
    <div id="pie-gender">
        <a class="reset" href="javascript:usChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
        <span class="reset" style="display: none;"> | Current filter: <span class="filter"></span></span>
        <div class="clearfix"></div>
    </div>
    <div id="pie-age">
        <a class="reset" href="javascript:usChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
        <span class="reset" style="display: none;"> | Current filter: <span class="filter"></span></span>
        <div class="clearfix"></div>
    </div>
     <div>
        <a href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a>
    </div>
    <script type="text/javascript">
        d3.csv("data/gender.csv", function (data) {
            d3.json("data/us-states.json", function (json){

                // set up crossfilter on the data.
                var ndx = crossfilter(data);

                // set up the dimensions
                var stateDim = ndx.dimension(function (d) { return d.state; });
                var genderDim = ndx.dimension(function(d) { return d.gender; });
                var ageDim = ndx.dimension(function(d) { return d.age; });

                //filtering age ranges
                var age_0_18 = ageDim.filter([0,19]);
                var age_19_30 = ageDim.filter([19,31]);
                var age_31_60 = ageDim.filter([31,61]);
                var age_61_101 = ageDim.filter([61,101]);


                // set up the groups/values
                var state = stateDim.group();
                var gender = genderDim.group(); 
                //var age = ageDim.group();
                var age1 = age_0_18.group();
                var age2 = age_19_30.group();
                var age3 = age_31_60.group();
                var age4 = age_61_101.group();

                // the different charts - options are set below for each one.
                var pieGender = dc.pieChart('#pie-gender');
                var pieAge = dc.pieChart('#pie-age')
                var usmap = dc.geoChoroplethChart("#map");

                //create pie to show gender
                pieGender
                    .width(180)
                    .height(180)
                    .radius(80)
                    .dimension(genderDim)
                    .group(gender)
                    .renderLabel(true)
                    .innerRadius(10)
                    .transitionDuration(500)
                    //.colorAccessor(function (d, i) { return d.value; });
                    //below is how to decide the colours for pie slices
                    .colors(d3.scale.ordinal().range([ '#14CAFF', '#4646FF']));

                //creating pie to show age
                pieAge
                    .width(180)
                    .height(180)
                    .radius(80)
                    .dimension(ageDim)
                    .group(age1,age2,age3,age4)
                    .renderLabel(true)
                    .innerRadius(10)
                    .transitionDuration(500)
                    .colorAccessor(function (d, i) { return d.value; });


                //display US map                    
                usmap
                    .width(900)
                    .height(500)
                    .dimension(stateDim)
                    .group(state)
                    .colors(["rgb(20,202,255)","rgb(70,70,255)"])
                    .overlayGeoJson(json.features, "name", function (d) { return d.properties.name; })      

                // at the end this needs to be called to actually go through and generate all the graphs on the page.
                dc.renderAll();
            }); 
        });             
    </script>
</body>

我尝试使用过滤器然后分组,但结果保持不变。我认为程序错了。

非常感谢任何帮助。感谢。

1 个答案:

答案 0 :(得分:1)

我确定我已经看过很多这方面的例子,但我无法通过快速搜索找到任何例子。

您希望使用group's groupValue function将年龄纳入您想要的类别。这与您舍入值或进行任何其他分类的方式完全相同:

var ageGroup = ageDim.group(function(v) {
  if(v < 19) return "18 or under";
  else if(v < 30) return "19-29";
  else if(v < 30) return "30-59";
  else return "over 60";
});

请注意,dimension.filter()只返回维度并更改整个交叉过滤器的过滤器,因此上面的所有组都是同一个组,只有最后一个过滤器才会使用。