Grouping and Drill-Down

This example shows how you can leverage the grouping features in the CollectionView class to create drill-down charts.

Click on the bars to drill-down into any group. The chart will be updated to show the new data, and the chart's header will show breadcrumbs so you can navigate back up the group hierarchy:

JapanFranceCanadaItalyUSGermanyUKKoreaChinaCountry0200400Sales (US$ thousands)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// This file locates: "Scripts/Lesson/C1FlexChart/GroupingDrillDown.js".
c1.documentReady(function () {
    var theChart = wijmo.Control.getControl('#theChart');
 
    // create a CollectionView containing data grouped by
    // country, product, color, and type
    var view = new wijmo.collections.CollectionView(getData(), {
        groupDescriptions: 'country,product,color,type'.split(',')
    });
 
    theChart.itemsSource = getGroupData(view); // show first-level grouping
    theChart.selectionChanged.addHandler(function (s, e) {
        if (s.selection) {
            var point = s.selection.collectionView.currentItem;
            if (point && point.group && !point.group.isBottomLevel) {
                showGroup(point.group);
            }
        }
    })
 
     
 
    // show a group on the chart
    function showGroup(group) {
 
        // update titles
        updateChartHeader(group);
        var level = 'level' in group ? group.level + 1 : 0;
        theChart.axisX.title = wijmo.toHeaderCase(view.groupDescriptions[level].propertyName);
 
        // update the series color (use a different one for each level)
        var palette = theChart.palette || wijmo.chart.Palettes.standard;
        theChart.series[0].style = {
            fill: palette[level],
            stroke: palette[level]
        };
 
        // update data
        theChart.itemsSource = getGroupData(group);
        theChart.selection = null;
    }
 
    // update the chart header element
    var header = document.getElementById('header');
    function updateChartHeader(group) {
        var item = group.items[0],
          path = '',
          headers = [];
        for (var i = 0; i <= group.level; i++) {
            var prop = view.groupDescriptions[i].propertyName,
              hdr = wijmo.format('<a href="#{path}">{prop}</a>: {value}', {
                  path: path,
                  prop: wijmo.toHeaderCase(prop),
                  value: item[prop]
              });
            headers.push(hdr);
            path += '/' + item[prop];
        }
        header.innerHTML = headers.length > 0
            ? 'Sales for ' + headers.join(', ')
          : 'Sales';
    }
 
    // handle clicks on chart's header element to navigate back up
    header.addEventListener('click', function (e) {
        if (e.target instanceof HTMLAnchorElement) {
            e.preventDefault();
 
            // get the link path
            var path = e.target.href;
            path = path.substr(path.lastIndexOf('#') + 1);
            path = path.split('/');
 
            // find the group that matches the path
            var src = view;
            for (var i = 1; i < path.length; i++) {
                for (var j = 0; j < src.groups.length; j++) {
                    var group = src.groups[j];
                    if (group.name == path[i]) {
                        src = group;
                        break;
                    }
                }
            }
 
            // show the selected group
            showGroup(src);
        }
    });
 
    // get the group data for a selected point
    function getGroupData(group) {
 
        // get items for this group, aggregate by sales
        var arr = [];
        group.groups.forEach(function (g) {
            arr.push({
                name: g.name,
                sales: g.getAggregate('Sum', 'sales'),
                group: g
            });
        });
 
        // return a new collection view sorted by sales
        return new wijmo.collections.CollectionView(arr, {
            sortDescriptions: [
              new wijmo.collections.SortDescription('sales', false)
            ]
        });
    }
 
    // create some random data
    function getData() {
        var countries = 'US,Canada,Germany,UK,France,Italy,Japan,Korea,China'.split(',');
        var products = 'Piano,Violin,Flute,Guitar,Cello'.split(',');
        var colors = 'Red,Green,Blue,Brown,White,Black'.split(',');
        var types = 'Hobbyist,Average,Professional,Collector'.split(',');
        var data = [];
        for (var i = 0; i < 1000; i++) {
            data.push({
                id: i,
                country: randomItem(countries),
                product: randomItem(products),
                color: randomItem(colors),
                type: randomItem(types),
                sales: Math.random() * 10000,
                expenses: Math.random() * 5000
            });
        }
        return data;
    }
 
    function randomItem(items) {
        return items[Math.floor(Math.random() * items.length)];
    }
});
1
2
3
4
5
6
7
8
9
10
// This file locates: "Content/css/Lesson/C1FlexChart/GroupingDrillDown.css".
.chart-host {
  border: 1px solid #e4e4e4;
}
.chart-host h4 {
  text-align: center;
}
.chart-host a {
  cursor: pointer;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Web.Mvc;
 
namespace LearnMvcClient.Controllers
{
    public partial class C1FlexChartController : Controller
    {
        // GET: GroupingDrillDown
        public ActionResult GroupingDrillDown()
        {
            return View();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<h1>
    @Html.Raw(Resources.C1FlexChart.GroupingDrillDown_Title)
</h1>
 
<p>
    @Html.Raw(Resources.C1FlexChart.GroupingDrillDown_Text1)
</p>
<p>
    @Html.Raw(Resources.C1FlexChart.GroupingDrillDown_Text2)
</p>
 
<div class="chart-host">
    <h4 id="header">@Html.Raw(Resources.C1FlexChart.GroupingDrillDown_Text3)</h4>
    @(Html.C1().FlexChart().Id("theChart")
        .BindingX("name")
        .Series(sb=>sb.Add().Binding("sales").Name("Sales"))
        .AxisX(x=>x.Title("Country"))
        .AxisY(y=>y.Title("Sales (US$ thousands)").Format("n0,"))
        .Legend(C1.Web.Mvc.Chart.Position.None)
        .Tooltip(t=>t.Content(""))
        .SelectionMode(C1.Web.Mvc.Chart.SelectionMode.Point)
    )
</div>