4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../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.
24 * As with all other series, the Radar series must be appended in the *series* Chart array configuration. See the Chart
25 * documentation for more information. A typical configuration object for the radar series could be:
27 * {@img Ext.chart.series.Radar/Ext.chart.series.Radar.png Ext.chart.series.Radar chart series}
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 categories field, `name` but bound to different properties for each category,
100 * `data1`, `data2` and `data3` respectively. All series display markers by having `showMarkers` enabled. The configuration for the markers of each series can be set by adding properties onto
101 * the markerConfig object. Finally we override some theme styling properties by adding properties to the `style` object.
105 Ext.define('Ext.chart.series.Radar', {
107 /* Begin Definitions */
109 extend: 'Ext.chart.series.Series',
111 requires: ['Ext.chart.Shape', 'Ext.fx.Anim'],
113 /* End Definitions */
115 type: "radar",
116 alias: 'series.radar',
123 <span id='Ext-chart-series-Radar-cfg-style'> /**
124 </span> * @cfg {Object} style
125 * An object containing styles for overriding series styles from Theming.
129 constructor: function(config) {
130 this.callParent(arguments);
132 surface = me.chart.surface, i, l;
133 me.group = surface.getGroup(me.seriesId);
134 if (me.showMarkers) {
135 me.markerGroup = surface.getGroup(me.seriesId + '-markers');
139 <span id='Ext-chart-series-Radar-method-drawSeries'> /**
140 </span> * Draws the series for the current chart.
142 drawSeries: function() {
144 store = me.chart.substore || me.chart.store,
148 animate = chart.animate,
149 field = me.field || me.yField,
150 surface = chart.surface,
151 chartBBox = chart.chartBBox,
162 l = store.getCount(),
163 startPath, path, x, y, rho,
165 seriesStyle = me.seriesStyle,
166 seriesLabelStyle = me.seriesLabelStyle,
167 first = chart.resizing || !me.radar,
168 axis = chart.axes && chart.axes.get(0),
169 aggregate = !(axis && axis.maximum);
173 maxValue = aggregate? 0 : (axis.maximum || 0);
175 Ext.apply(seriesStyle, me.style || {});
177 //if the store is empty then there's nothing to draw
178 if (!store || !store.getCount()) {
182 me.unHighlightItem();
183 me.cleanHighlights();
185 centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
186 centerY = me.centerY = chartBBox.y + (chartBBox.height / 2);
187 me.radius = radius = Math.min(chartBBox.width, chartBBox.height) /2;
188 me.items = items = [];
191 //get all renderer fields
192 chart.series.each(function(series) {
193 fields.push(series.yField);
195 //get maxValue to interpolate
196 store.each(function(record, i) {
197 for (i = 0, nfields = fields.length; i < nfields; i++) {
198 maxValue = max(+record.get(fields[i]), maxValue);
202 //ensure non-zero value.
203 maxValue = maxValue || 1;
204 //create path and items
205 startPath = []; path = [];
206 store.each(function(record, i) {
207 rho = radius * record.get(field) / maxValue;
208 x = rho * cos(i / l * pi2);
209 y = rho * sin(i / l * pi2);
211 path.push('M', x + centerX, y + centerY);
212 startPath.push('M', 0.01 * x + centerX, 0.01 * y + centerY);
214 path.push('L', x + centerX, y + centerY);
215 startPath.push('L', 0.01 * x + centerX, 0.01 * y + centerY);
218 sprite: false, //TODO(nico): add markers
219 point: [centerX + x, centerY + y],
226 me.radar = surface.add(Ext.apply({
230 }, seriesStyle || {}));
233 if (chart.resizing) {
234 me.radar.setAttributes({
240 me.onAnimate(me.radar, {
243 }, seriesStyle || {})
246 me.radar.setAttributes(Ext.apply({
248 }, seriesStyle || {}), true);
250 //render markers, labels and callouts
251 if (me.showMarkers) {
258 // @private draws the markers for the lines (if any).
259 drawMarkers: function() {
262 surface = chart.surface,
263 markerStyle = Ext.apply({}, me.markerStyle || {}),
264 endMarkerStyle = Ext.apply(markerStyle, me.markerConfig),
266 type = endMarkerStyle.type,
267 markerGroup = me.markerGroup,
268 centerX = me.centerX,
269 centerY = me.centerY,
272 delete endMarkerStyle.type;
274 for (i = 0, l = items.length; i < l; i++) {
276 marker = markerGroup.getAt(i);
278 marker = Ext.chart.Shape[type](surface, Ext.apply({
291 if (chart.resizing) {
292 marker.setAttributes({
309 me.onAnimate(marker, {
314 marker.setAttributes(Ext.apply(marker._to, endMarkerStyle || {}), true);
319 isItemInPoint: function(x, y, item) {
324 return (abs(point[0] - x) <= tolerance &&
325 abs(point[1] - y) <= tolerance);
328 // @private callback for when creating a label sprite.
329 onCreateLabel: function(storeItem, item, i, display) {
331 group = me.labelsGroup,
333 centerX = me.centerX,
334 centerY = me.centerY,
336 endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config);
338 return me.chart.surface.add(Ext.apply({
340 'text-anchor': 'middle',
347 // @private callback for when placing a label sprite.
348 onPlaceLabel: function(label, storeItem, item, i, display, animate) {
351 resizing = chart.resizing,
353 format = config.renderer,
354 field = config.field,
355 centerX = me.centerX,
356 centerY = me.centerY,
364 label.setAttributes({
365 text: format(storeItem.get(field)),
371 label.setAttributes({
379 me.onAnimate(label, {
383 label.setAttributes(opt, true);
388 // @private for toggling (show/hide) series.
389 toggleAll: function(show) {
391 i, ln, shadow, shadows;
393 Ext.chart.series.Radar.superclass.hideAll.call(me);
396 Ext.chart.series.Radar.superclass.showAll.call(me);
399 me.radar.setAttributes({
403 if (me.radar.shadows) {
404 for (i = 0, shadows = me.radar.shadows, ln = shadows.length; i < ln; i++) {
406 shadow.setAttributes({
414 // @private hide all elements in the series.
415 hideAll: function() {
416 this.toggleAll(false);
420 // @private show all elements in the series.
421 showAll: function() {
422 this.toggleAll(true);
425 // @private hide all markers that belong to `markerGroup`
426 hideMarkers: function(index) {
428 count = me.markerGroup && me.markerGroup.getCount() || 0,
430 for (; i < count; i++) {
431 me.markerGroup.getAt(i).hide(true);