123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-chart-series-Radar'>/**
- </span> * @class Ext.chart.series.Radar
- *
- * Creates a Radar Chart. A Radar Chart is a useful visualization technique for comparing different quantitative values for
- * a constrained number of categories.
- *
- * As with all other series, the Radar series must be appended in the *series* Chart array configuration. See the Chart
- * documentation for more information. A typical configuration object for the radar series could be:
- *
- * @example
- * var store = Ext.create('Ext.data.JsonStore', {
- * fields: ['name', 'data1', 'data2', 'data3'],
- * data: [
- * { 'name': 'metric one', 'data1': 14, 'data2': 12, 'data3': 13 },
- * { 'name': 'metric two', 'data1': 16, 'data2': 8, 'data3': 3 },
- * { 'name': 'metric three', 'data1': 14, 'data2': 2, 'data3': 7 },
- * { 'name': 'metric four', 'data1': 6, 'data2': 14, 'data3': 23 },
- * { 'name': 'metric five', 'data1': 36, 'data2': 38, 'data3': 33 }
- * ]
- * });
- *
- * Ext.create('Ext.chart.Chart', {
- * renderTo: Ext.getBody(),
- * width: 500,
- * height: 300,
- * animate: true,
- * theme:'Category2',
- * store: store,
- * axes: [{
- * type: 'Radial',
- * position: 'radial',
- * label: {
- * display: true
- * }
- * }],
- * series: [{
- * type: 'radar',
- * xField: 'name',
- * yField: 'data1',
- * showInLegend: true,
- * showMarkers: true,
- * markerConfig: {
- * radius: 5,
- * size: 5
- * },
- * style: {
- * 'stroke-width': 2,
- * fill: 'none'
- * }
- * },{
- * type: 'radar',
- * xField: 'name',
- * yField: 'data2',
- * showMarkers: true,
- * showInLegend: true,
- * markerConfig: {
- * radius: 5,
- * size: 5
- * },
- * style: {
- * 'stroke-width': 2,
- * fill: 'none'
- * }
- * },{
- * type: 'radar',
- * xField: 'name',
- * yField: 'data3',
- * showMarkers: true,
- * showInLegend: true,
- * markerConfig: {
- * radius: 5,
- * size: 5
- * },
- * style: {
- * 'stroke-width': 2,
- * fill: 'none'
- * }
- * }]
- * });
- *
- * 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, `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 the markerConfig object.
- * Finally we override some theme styling properties by adding properties to the `style` object.
- *
- * @xtype radar
- */
- Ext.define('Ext.chart.series.Radar', {
- /* Begin Definitions */
- extend: 'Ext.chart.series.Series',
- requires: ['Ext.chart.Shape', 'Ext.fx.Anim'],
- /* End Definitions */
- type: "radar",
- alias: 'series.radar',
- rad: Math.PI / 180,
- showInLegend: false,
- <span id='Ext-chart-series-Radar-cfg-style'> /**
- </span> * @cfg {Object} style
- * An object containing styles for overriding series styles from Theming.
- */
- style: {},
- constructor: function(config) {
- this.callParent(arguments);
- var me = this,
- surface = me.chart.surface, i, l;
- me.group = surface.getGroup(me.seriesId);
- if (me.showMarkers) {
- me.markerGroup = surface.getGroup(me.seriesId + '-markers');
- }
- },
- <span id='Ext-chart-series-Radar-method-drawSeries'> /**
- </span> * Draws the series for the current chart.
- */
- drawSeries: function() {
- var me = this,
- store = me.chart.getChartStore(),
- data = store.data.items,
- d, record,
- group = me.group,
- sprite,
- chart = me.chart,
- seriesItems = chart.series.items,
- s, sLen, series,
- animate = chart.animate,
- field = me.field || me.yField,
- surface = chart.surface,
- chartBBox = chart.chartBBox,
- seriesIdx = me.seriesIdx,
- colorArrayStyle = me.colorArrayStyle,
- centerX, centerY,
- items,
- radius,
- maxValue = 0,
- fields = [],
- max = Math.max,
- cos = Math.cos,
- sin = Math.sin,
- pi2 = Math.PI * 2,
- l = store.getCount(),
- startPath, path, x, y, rho,
- i, nfields,
- seriesStyle = me.seriesStyle,
- seriesLabelStyle = me.seriesLabelStyle,
- first = chart.resizing || !me.radar,
- axis = chart.axes && chart.axes.get(0),
- aggregate = !(axis && axis.maximum);
- me.setBBox();
-
- maxValue = aggregate? 0 : (axis.maximum || 0);
-
- Ext.apply(seriesStyle, me.style || {});
- //if the store is empty then there's nothing to draw
- if (!store || !store.getCount() || me.seriesIsHidden) {
- me.hide();
- me.items = [];
- if (me.radar) {
- me.radar.hide(true);
- }
- me.radar = null;
- return;
- }
-
- if(!seriesStyle['stroke']){
- seriesStyle['stroke'] = colorArrayStyle[seriesIdx % colorArrayStyle.length];
- }
- me.unHighlightItem();
- me.cleanHighlights();
- centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
- centerY = me.centerY = chartBBox.y + (chartBBox.height / 2);
- me.radius = radius = Math.min(chartBBox.width, chartBBox.height) /2;
- me.items = items = [];
- if (aggregate) {
- //get all renderer fields
- for (s = 0, sLen = seriesItems.length; s < sLen; s++) {
- series = seriesItems[s];
- fields.push(series.yField);
- }
- //get maxValue to interpolate
- for (d = 0; d < l; d++) {
- record = data[d];
- for (i = 0, nfields = fields.length; i < nfields; i++) {
- maxValue = max(+record.get(fields[i]), maxValue);
- }
- }
- }
- //ensure non-zero value.
- maxValue = maxValue || 1;
- //create path and items
- startPath = []; path = [];
- for (i = 0; i < l; i++) {
- record = data[i];
- rho = radius * record.get(field) / maxValue;
- x = rho * cos(i / l * pi2);
- y = rho * sin(i / l * pi2);
- if (i == 0) {
- path.push('M', x + centerX, y + centerY);
- startPath.push('M', 0.01 * x + centerX, 0.01 * y + centerY);
- } else {
- path.push('L', x + centerX, y + centerY);
- startPath.push('L', 0.01 * x + centerX, 0.01 * y + centerY);
- }
- items.push({
- sprite: false, //TODO(nico): add markers
- point: [centerX + x, centerY + y],
- storeItem: record,
- series: me
- });
- }
- path.push('Z');
- //create path sprite
- if (!me.radar) {
- me.radar = surface.add(Ext.apply({
- type: 'path',
- group: group,
- path: startPath
- }, seriesStyle || {}));
- }
- //reset on resizing
- if (chart.resizing) {
- me.radar.setAttributes({
- path: startPath
- }, true);
- }
- //render/animate
- if (chart.animate) {
- me.onAnimate(me.radar, {
- to: Ext.apply({
- path: path
- }, seriesStyle || {})
- });
- } else {
- me.radar.setAttributes(Ext.apply({
- path: path
- }, seriesStyle || {}), true);
- }
- //render markers, labels and callouts
- if (me.showMarkers) {
- me.drawMarkers();
- }
- me.renderLabels();
- me.renderCallouts();
- },
- // @private draws the markers for the lines (if any).
- drawMarkers: function() {
- var me = this,
- chart = me.chart,
- surface = chart.surface,
- markerStyle = Ext.apply({}, me.markerStyle || {}),
- endMarkerStyle = Ext.apply(markerStyle, me.markerConfig, {
- fill: me.colorArrayStyle[me.seriesIdx % me.colorArrayStyle.length]
- }),
- items = me.items,
- type = endMarkerStyle.type,
- markerGroup = me.markerGroup,
- centerX = me.centerX,
- centerY = me.centerY,
- item, i, l, marker;
- delete endMarkerStyle.type;
- for (i = 0, l = items.length; i < l; i++) {
- item = items[i];
- marker = markerGroup.getAt(i);
- if (!marker) {
- marker = Ext.chart.Shape[type](surface, Ext.apply({
- group: markerGroup,
- x: 0,
- y: 0,
- translate: {
- x: centerX,
- y: centerY
- }
- }, endMarkerStyle));
- }
- else {
- marker.show();
- }
- item.sprite = marker;
- if (chart.resizing) {
- marker.setAttributes({
- x: 0,
- y: 0,
- translate: {
- x: centerX,
- y: centerY
- }
- }, true);
- }
- marker._to = {
- translate: {
- x: item.point[0],
- y: item.point[1]
- }
- };
- //render/animate
- if (chart.animate) {
- me.onAnimate(marker, {
- to: marker._to
- });
- }
- else {
- marker.setAttributes(Ext.apply(marker._to, endMarkerStyle || {}), true);
- }
- }
- },
- isItemInPoint: function(x, y, item) {
- var point,
- tolerance = 10,
- abs = Math.abs;
- point = item.point;
- return (abs(point[0] - x) <= tolerance &&
- abs(point[1] - y) <= tolerance);
- },
- // @private callback for when creating a label sprite.
- onCreateLabel: function(storeItem, item, i, display) {
- var me = this,
- group = me.labelsGroup,
- config = me.label,
- centerX = me.centerX,
- centerY = me.centerY,
- point = item.point,
- endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config);
- return me.chart.surface.add(Ext.apply({
- 'type': 'text',
- 'text-anchor': 'middle',
- 'group': group,
- 'x': centerX,
- 'y': centerY
- }, config || {}));
- },
- // @private callback for when placing a label sprite.
- onPlaceLabel: function(label, storeItem, item, i, display, animate) {
- var me = this,
- chart = me.chart,
- resizing = chart.resizing,
- config = me.label,
- format = config.renderer,
- field = config.field,
- centerX = me.centerX,
- centerY = me.centerY,
- opt = {
- x: item.point[0],
- y: item.point[1]
- },
- x = opt.x - centerX,
- y = opt.y - centerY;
- label.setAttributes({
- text: format(storeItem.get(field)),
- hidden: true
- },
- true);
- if (resizing) {
- label.setAttributes({
- x: centerX,
- y: centerY
- }, true);
- }
- if (animate) {
- label.show(true);
- me.onAnimate(label, {
- to: opt
- });
- } else {
- label.setAttributes(opt, true);
- label.show(true);
- }
- },
- // @private for toggling (show/hide) series.
- toggleAll: function(show) {
- var me = this,
- i, ln, shadow, shadows;
- if (!show) {
- Ext.chart.series.Radar.superclass.hideAll.call(me);
- }
- else {
- Ext.chart.series.Radar.superclass.showAll.call(me);
- }
- if (me.radar) {
- me.radar.setAttributes({
- hidden: !show
- }, true);
- //hide shadows too
- if (me.radar.shadows) {
- for (i = 0, shadows = me.radar.shadows, ln = shadows.length; i < ln; i++) {
- shadow = shadows[i];
- shadow.setAttributes({
- hidden: !show
- }, true);
- }
- }
- }
- },
- // @private hide all elements in the series.
- hideAll: function() {
- this.toggleAll(false);
- this.hideMarkers(0);
- },
- // @private show all elements in the series.
- showAll: function() {
- this.toggleAll(true);
- },
- // @private hide all markers that belong to `markerGroup`
- hideMarkers: function(index) {
- var me = this,
- count = me.markerGroup && me.markerGroup.getCount() || 0,
- i = index || 0;
- for (; i < count; i++) {
- me.markerGroup.getAt(i).hide(true);
- }
- }
- });
- </pre>
- </body>
- </html>
|