4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-chart-series-Radar'>/**
19 </span> * @class Ext.chart.series.Radar
20 * @extends Ext.chart.series.Series
22 * Creates a Radar Chart. A Radar Chart is a useful visualization technique for comparing different quantitative values for
23 * a constrained number of categories.
25 * As with all other series, the Radar series must be appended in the *series* Chart array configuration. See the Chart
26 * documentation for more information. A typical configuration object for the radar series could be:
29 * var store = Ext.create('Ext.data.JsonStore', {
30 * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
32 * { 'name': 'metric one', 'data1': 10, 'data2': 12, 'data3': 14, 'data4': 8, 'data5': 13 },
33 * { 'name': 'metric two', 'data1': 7, 'data2': 8, 'data3': 16, 'data4': 10, 'data5': 3 },
34 * { 'name': 'metric three', 'data1': 5, 'data2': 2, 'data3': 14, 'data4': 12, 'data5': 7 },
35 * { 'name': 'metric four', 'data1': 2, 'data2': 14, 'data3': 6, 'data4': 1, 'data5': 23 },
36 * { 'name': 'metric five', 'data1': 27, 'data2': 38, 'data3': 36, 'data4': 13, 'data5': 33 }
40 * Ext.create('Ext.chart.Chart', {
41 * renderTo: Ext.getBody(),
99 * In this configuration we add three series to the chart. Each of these series is bound to the same
100 * categories field, `name` but bound to different properties for each category, `data1`, `data2` and
101 * `data3` respectively. All series display markers by having `showMarkers` enabled. The configuration
102 * for the markers of each series can be set by adding properties onto the markerConfig object.
103 * Finally we override some theme styling properties by adding properties to the `style` object.
107 Ext.define('Ext.chart.series.Radar', {
109 /* Begin Definitions */
111 extend: 'Ext.chart.series.Series',
113 requires: ['Ext.chart.Shape', 'Ext.fx.Anim'],
115 /* End Definitions */
117 type: "radar",
118 alias: 'series.radar',
125 <span id='Ext-chart-series-Radar-cfg-style'> /**
126 </span> * @cfg {Object} style
127 * An object containing styles for overriding series styles from Theming.
131 constructor: function(config) {
132 this.callParent(arguments);
134 surface = me.chart.surface, i, l;
135 me.group = surface.getGroup(me.seriesId);
136 if (me.showMarkers) {
137 me.markerGroup = surface.getGroup(me.seriesId + '-markers');
141 <span id='Ext-chart-series-Radar-method-drawSeries'> /**
142 </span> * Draws the series for the current chart.
144 drawSeries: function() {
146 store = me.chart.getChartStore(),
150 animate = chart.animate,
151 field = me.field || me.yField,
152 surface = chart.surface,
153 chartBBox = chart.chartBBox,
164 l = store.getCount(),
165 startPath, path, x, y, rho,
167 seriesStyle = me.seriesStyle,
168 seriesLabelStyle = me.seriesLabelStyle,
169 first = chart.resizing || !me.radar,
170 axis = chart.axes && chart.axes.get(0),
171 aggregate = !(axis && axis.maximum);
175 maxValue = aggregate? 0 : (axis.maximum || 0);
177 Ext.apply(seriesStyle, me.style || {});
179 //if the store is empty then there's nothing to draw
180 if (!store || !store.getCount()) {
184 me.unHighlightItem();
185 me.cleanHighlights();
187 centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
188 centerY = me.centerY = chartBBox.y + (chartBBox.height / 2);
189 me.radius = radius = Math.min(chartBBox.width, chartBBox.height) /2;
190 me.items = items = [];
193 //get all renderer fields
194 chart.series.each(function(series) {
195 fields.push(series.yField);
197 //get maxValue to interpolate
198 store.each(function(record, i) {
199 for (i = 0, nfields = fields.length; i < nfields; i++) {
200 maxValue = max(+record.get(fields[i]), maxValue);
204 //ensure non-zero value.
205 maxValue = maxValue || 1;
206 //create path and items
207 startPath = []; path = [];
208 store.each(function(record, i) {
209 rho = radius * record.get(field) / maxValue;
210 x = rho * cos(i / l * pi2);
211 y = rho * sin(i / l * pi2);
213 path.push('M', x + centerX, y + centerY);
214 startPath.push('M', 0.01 * x + centerX, 0.01 * y + centerY);
216 path.push('L', x + centerX, y + centerY);
217 startPath.push('L', 0.01 * x + centerX, 0.01 * y + centerY);
220 sprite: false, //TODO(nico): add markers
221 point: [centerX + x, centerY + y],
228 me.radar = surface.add(Ext.apply({
232 }, seriesStyle || {}));
235 if (chart.resizing) {
236 me.radar.setAttributes({
242 me.onAnimate(me.radar, {
245 }, seriesStyle || {})
248 me.radar.setAttributes(Ext.apply({
250 }, seriesStyle || {}), true);
252 //render markers, labels and callouts
253 if (me.showMarkers) {
260 // @private draws the markers for the lines (if any).
261 drawMarkers: function() {
264 surface = chart.surface,
265 markerStyle = Ext.apply({}, me.markerStyle || {}),
266 endMarkerStyle = Ext.apply(markerStyle, me.markerConfig),
268 type = endMarkerStyle.type,
269 markerGroup = me.markerGroup,
270 centerX = me.centerX,
271 centerY = me.centerY,
274 delete endMarkerStyle.type;
276 for (i = 0, l = items.length; i < l; i++) {
278 marker = markerGroup.getAt(i);
280 marker = Ext.chart.Shape[type](surface, Ext.apply({
293 if (chart.resizing) {
294 marker.setAttributes({
311 me.onAnimate(marker, {
316 marker.setAttributes(Ext.apply(marker._to, endMarkerStyle || {}), true);
321 isItemInPoint: function(x, y, item) {
326 return (abs(point[0] - x) <= tolerance &&
327 abs(point[1] - y) <= tolerance);
330 // @private callback for when creating a label sprite.
331 onCreateLabel: function(storeItem, item, i, display) {
333 group = me.labelsGroup,
335 centerX = me.centerX,
336 centerY = me.centerY,
338 endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config);
340 return me.chart.surface.add(Ext.apply({
342 'text-anchor': 'middle',
349 // @private callback for when placing a label sprite.
350 onPlaceLabel: function(label, storeItem, item, i, display, animate) {
353 resizing = chart.resizing,
355 format = config.renderer,
356 field = config.field,
357 centerX = me.centerX,
358 centerY = me.centerY,
366 label.setAttributes({
367 text: format(storeItem.get(field)),
373 label.setAttributes({
381 me.onAnimate(label, {
385 label.setAttributes(opt, true);
390 // @private for toggling (show/hide) series.
391 toggleAll: function(show) {
393 i, ln, shadow, shadows;
395 Ext.chart.series.Radar.superclass.hideAll.call(me);
398 Ext.chart.series.Radar.superclass.showAll.call(me);
401 me.radar.setAttributes({
405 if (me.radar.shadows) {
406 for (i = 0, shadows = me.radar.shadows, ln = shadows.length; i < ln; i++) {
408 shadow.setAttributes({
416 // @private hide all elements in the series.
417 hideAll: function() {
418 this.toggleAll(false);
422 // @private show all elements in the series.
423 showAll: function() {
424 this.toggleAll(true);
427 // @private hide all markers that belong to `markerGroup`
428 hideMarkers: function(index) {
430 count = me.markerGroup && me.markerGroup.getCount() || 0,
432 for (; i < count; i++) {
433 me.markerGroup.getAt(i).hide(true);