Wijmo

Sunburst 101

This page shows how to get started with Wijmo's Sunburst chart control.

Getting Started

Here are the steps for getting started with the Sunburst chart control in AngularJS applications:

  1. Add references to AngularJS, Wijmo, and Wijmo's AngularJS directives.
  2. Include the Wijmo directives in the app module:
    var app = angular.module('app', ['wj']);
  3. Add a controller to provide data and logic.
  4. Add a Wijmo Sunburst chart control to the page and bind it to your data.
  5. (Optional) Add some CSS to customize the control's appearance.
HTML
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/> <link rel="stylesheet" type="text/css" href="css/wijmo.css" /> <link href="css/app.css" rel="stylesheet" type="text/css" /> <script src="scripts/angular.js" type="text/javascript"></script> <script src="scripts/wijmo.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.hierarchical.js" type="text/javascript"></script> <script src="scripts/wijmo.angular.js" type="text/javascript"></script> <script src="scripts/app.js" type="text/javascript"></script> </head> <body ng-app="app" ng-controller="appCtrl"> <!-- this is the Sunburst directive --> <wj-sunburst control="chart" items-source="itemsSource" binding="value" binding-name="bindngName"> </wj-sunburst> </body> </html>
JS
// declare app module var app = angular.module('app', ['wj']); // controller provides data app.controller('simpleCtrl', function appCtrl($scope) { // create controls var data = [], times = [['Jan', 'Feb', 'Mar'], ['Apr', 'May', 'June'], ['Jul', 'Aug', 'Sep'], ['Oct', 'Nov', 'Dec']], years = [], year = new Date().getFullYear(), yearLen, i; yearLen = Math.max(Math.round(Math.abs(5 - Math.random() * 10)), 3); for (i = yearLen; i > 0; i--) { years.push(year - i); } // populate itemsSource years.forEach(y => { var addQuarter = Math.random() > 0.5; if (addQuarter) { times.forEach((q, idx) => { var addMonth = Math.random() > 0.5, quar = 'Q' + (idx + 1); if (addMonth) { q.forEach(m => { data.push({ year: y.toString(), quarter: quar, month: m, value: Math.round(Math.random() * 100) }); }); } else { data.push({ year: y.toString(), quarter: quar, value: Math.round(Math.random() * 400) }); } }); } else { data.push({ year: y.toString(), value: Math.round(Math.random() * 1200) }); } }); $scope.chart = null; $scope.bindingName = ['year', 'quarter', 'month']; $scope.$watch('chart', function () { if ($scope.chart) { $scope.chart.dataLabel.position = wijmo.chart.PieLabelPosition.Center; $scope.chart.dataLabel.content = '{name}'; } }); $scope.itemsSource = data; });

Result (live):

Group Collection

The sample shows how to use the Sunburst chart with Grouped CollectionView.

HTML
<wj-sunburst control="chart" items-source="itemsSource" binding="value" </wj-sunburst>
JS
// declare app module var app = angular.module('app', ['wj']); // controller provides data app.controller('simpleCtrl', function appCtrl($scope) { function getGroupCVData() { var data = [], quarters = ['Q1', 'Q2', 'Q3', 'Q4'], months = [[{ name: 'Jan', value: 1 }, { name: 'Feb', value: 2 }, { name: 'Mar', value: 3 }], [{ name: 'Apr', value: 4 }, { name: 'May', value: 5 }, { name: 'June', value: 6 }], [{ name: 'Jul', value: 7 }, { name: 'Aug', value: 8 }, { name: 'Sep', value: 9 }], [{ name: 'Oct', value: 10 }, { name: 'Nov', value: 11 }, { name: 'Dec', value: 12 }]], years = [], year = new Date().getFullYear(), yearLen, i, len = 100; yearLen = 3; for (i = yearLen; i > 0; i--) { years.push(year - i); } var y, q, m; for (i = 0; i < len; i++) { y = Math.floor(Math.random() * yearLen); q = Math.floor(Math.random() * 4); m = Math.floor(Math.random() * 3); data.push({ year: years[y], quarter: quarters[q], month: months[q][m].name, monthVal: months[q][m].value, value: Math.round(Math.random() * 100) }); } var cv = new wijmo.collections.CollectionView(data); cv.sortDescriptions.push(new wijmo.collections.SortDescription('year', false)); cv.sortDescriptions.push(new wijmo.collections.SortDescription('quarter', false)); cv.sortDescriptions.push(new wijmo.collections.SortDescription('monthVal', false)); cv.groupDescriptions.push(new wijmo.collections.PropertyGroupDescription('year')); cv.groupDescriptions.push(new wijmo.collections.PropertyGroupDescription('quarter')); cv.groupDescriptions.push(new wijmo.collections.PropertyGroupDescription('month')); return cv; } $scope.chart = null; $scope.itemsSource = dataSvc.getGroupCVData(); $scope.$watch('chart', function () { if ($scope.chart) { $scope.chart.dataLabel.position = wijmo.chart.PieLabelPosition.Center; $scope.chart.dataLabel.content = '{name}'; } }); });

Result (live):

Basic Features

The Sunburst chart control has five basic properties that allow you to customize its layout and appearance:

The example below allows you to see what happens when you change these properties. Also, clicking on a sunburst slice will display a tooltip for the data point.

HTML
<wj-sunburst control="chart" items-source="itemsSource" binding="value" binding-name="bindingName" child-items-path="childItemsPath" inner-radius="{​{ innerRadius }}" offset="{​{ offset }}" start-angle="{​{ startAngle }}" reversed="{​{ reversed }}"> </wj-sunburst> <div class="form-horizontal"> <div class="form-group"> <label class="col-md-3 control-label">Inner Radius</label> <div class="col-md-9"> <wj-input-number control="inputInnerRadius" value="ctx.innerRadius" min="0" max="1" step=".1" format="n"> </wj-input-number> </div> </div> <div class="form-group"> <label class="col-md-3 control-label">Offset</label> <div class="col-md-9"> <wj-input-number control="inputOffset" value="ctx.offset" min="0" max="1" step=".1" format="n"> </wj-input-number> </div> </div> <div class="form-group"> <label class="col-md-3 control-label">Start Angle</label> <div class="col-md-9"> <wj-input-number control="inputStartAngle" value="ctx.startAngle" min="-360" max="360" step="45"> </wj-input-number> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <wj-menu header="Palette: <b>{​{ palette }}</b>" items-source="palettes" item-clicked="paletteChanged(s, e)"> </wj-menu> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <div class="checkbox"> <label> <input type="checkbox" ng-model="reversed"> Reversed? </label> </div> </div> </div> </div>
JS
$scope.itemsSource = dataSvc.getHierarchicalData(); $scope.chart = null; $scope.bindingName = ['year', 'quarter', 'month']; $scope.childItemsPath = 'items'; $scope.innerRadius = 0; $scope.offset = 0; $scope.startAngle = 0; $scope.reversed = false; $scope.palette = 'standard'; $scope.palettes = ['standard', 'cocoa', 'coral', 'dark', 'highcontrast', 'light', 'midnight', 'minimal', 'modern', 'organic', 'slate']; $scope.ctx = { innerRadius: 0, offset: 0, startAngle: 0 }; $scope.inputInnerRadius = null; $scope.inputOffset = null; $scope.inputStartAngle = null; $scope.$watch('chart', function () { if ($scope.chart) { $scope.chart.dataLabel.position = wijmo.chart.PieLabelPosition.Center; $scope.chart.dataLabel.content = '{name}'; } }); $scope.paletteChanged = function (sender) { var p = $scope.palettes[sender.selectedIndex]; $scope.palette = p; $scope.chart.palette = wijmo.chart.Palettes[p]; }; $scope.$watch('ctx.innerRadius', function () { var input = $scope.inputInnerRadius, val = $scope.ctx.innerRadius; if (!input || val < input.min || val > input.max) { return; } $scope.innerRadius = val; }); $scope.$watch('ctx.offset', function () { var input = $scope.inputOffset, val = $scope.ctx.offset; if (!input || val < input.min || val > input.max) { return; } $scope.offset = val; }); $scope.$watch('ctx.startAngle', function () { var input = $scope.inputStartAngle, val = $scope.ctx.startAngle; if (!input || val < input.min || val > input.max) { return; } $scope.startAngle = val; });

Result (live):

Legend and Titles

The legend properties can be used to customize the appearance of the chart's legend. You can also use the header and footer properties to add titles to the Sunburst chart control.

The following example allows you to change the Sunburst's legend.position, header, and footer properties in real-time.

HTML
<wj-sunburst items-source="itemsSource" binding="value" binding-name="bindingName" header="{​{ header }}" footer="{​{ footer }}"> <wj-flex-chart-legend position="{​{ legendPosition }}"></wj-flex-chart-legend> </wj-sunburst> <div class="form-horizontal"> <div class="form-group"> <label class="col-md-3 control-label">Header</label> <div class="col-md-9"> <input type="text" class="form-control" ng-model="header" placeholder="Specify the Sunburst's header" /> </div> </div> <div class="form-group"> <label class="col-md-3 control-label">Footer</label> <div class="col-md-9"> <input type="text" class="form-control" ng-model="footer" placeholder="Specify the Sunburst's footer" /> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <wj-menu header="Legend Position" value="legendPosition"> <wj-menu-item value="'None'">None</wj-menu-item> <wj-menu-item value="'Left'">Left</wj-menu-item> <wj-menu-item value="'Top'">Top</wj-menu-item> <wj-menu-item value="'Right'">Right</wj-menu-item> <wj-menu-item value="'Bottom'">Bottom</wj-menu-item> </wj-menu> </div> </div> </div>
JS
$scope.itemsSource = dataSvc.getData(); $scope.bindingName = ['year', 'quarter', 'month']; $scope.header = 'Fruit By Value'; $scope.footer = '2014 GrapeCity, inc.'; $scope.legendPosition = 'Right';

Result (live):

None Left Top Right Bottom

Selection

The Sunburst chart control allows you to select data points by clicking or touching a sunburst slice. Use the selectionMode property to specify whether you want to allow selection by data point or no selection at all (default).

Setting the selctionMode property to Point causes the Sunburst to update the selection property when the user clicks on a sunburst slice, and to apply the "wj-state-selected" class to the selected element. Setting the Sunburst's selectionMode property to Series or None will disable selections within the control.

The Sunburst chart offers three additional properties to customize the selection:

HTML
<wj-sunburst items-source="itemsSource" binding="value" binding-name="bindingName" selection-mode="Point" selected-item-position="{​{ selectedPosition }}" selected-item-offset="{​{ selectedOffset }}" is-animated="{​{ isAnimated }}"> </wj-sunburst> <div class="form-horizontal"> <div class="form-group"> <label class="col-md-3 control-label">Selected Item Offset</label> <div class="col-md-9"> <wj-input-number control="inputSelectedOffset" value="ctx.selectedOffset" min="0" max=".5" step=".1" format="n"> </wj-input-number> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <wj-menu header="Selected Item Position" value="selectedPosition"> <wj-menu-item value="'None'">None</wj-menu-item> <wj-menu-item value="'Left'">Left</wj-menu-item> <wj-menu-item value="'Top'">Top</wj-menu-item> <wj-menu-item value="'Right'">Right</wj-menu-item> <wj-menu-item value="'Bottom'">Bottom</wj-menu-item> </wj-menu> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <div class="checkbox"> <label> <input type="checkbox" ng-model="isAnimated"> Is Animated? </label> </div> </div> </div> </div>
JS
$scope.itemsSource = dataSvc.getData(); $scope.bindingName =: ['year', 'quarter', 'month']; $scope.selectedPosition = 'Top'; $scope.selectedOffset = 0; $scope.isAnimated = true; $scope.inputSelectedOffset = null; $scope.ctx = { selectedOffset: 0 }; $scope.$watch('ctx.selectedOffset', function () { var input = $scope.inputSelectedOffset, val = $scope.ctx.selectedOffset; if (!input || val < input.min || val > input.max) { return; } $scope.selectedOffset = val; });

Result (live):

None Left Top Right Bottom

Theming

The appearance of the Sunburst chart control is largely defined in CSS. In addition to a default theme, we include several professionally designed themes that customize the appearance of all Wijmo controls to achieve a consistent and attractive look.

You can customize the appearance of the Sunburst chart control using CSS. To do this, copy the CSS rules from the default theme to a new CSS file and modify the properties as needed.

In this example, we added the "custom-sunburst-chart" CSS class to the control and defined some CSS rules to change the fill, font family, and font weight of the header and fill color of the slices.

HTML
<wj-sunburst control="chart" items-source="itemsSource" binding="value" binding-name="name" header="Bullseye(target)" child-items-path="childItemsPath" class="custom-sunburst-chart"> <wj-flex-chart-legend position="None"></wj-flex-chart-legend> </wj-sunburst>
JS
$scope.itemsSource = dataSvc.getThemingData(); $scope.childItemsPath = 'items'; $scope.$watch('chart', function () { if ($scope.chart) { $scope.chart.tooltip.content = ''; } });
CSS
.custom-sunburst-chart.wj-sunburst .wj-header .wj-title { fill: #666; font-family: 'Courier New', Courier, monospace; font-weight: bold; } .custom-sunburst-chart.wj-sunburst ellipse, .custom-sunburst-chart.wj-sunburst path { stroke-width: 0; } .custom-sunburst-chart.wj-sunburst ellipse { fill: yellow; } .custom-sunburst-chart.wj-sunburst .slice-level2 > path { fill: red; } .custom-sunburst-chart.wj-sunburst .slice-level3 > path { fill: blue; } .custom-sunburst-chart.wj-sunburst .slice-level4 > path { fill: black; } .custom-sunburst-chart.wj-sunburst .slice-level5 > path { fill: white; stroke-width: 2; stroke: black; }

Result (live):