3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
15 Ext.require('Ext.chart.*');
16 Ext.require(['Ext.Window', 'Ext.fx.target.Sprite', 'Ext.layout.container.Fit']);
22 rgbToHsv: function(rgb) {
27 minVal = Math.min(r, g, b),
28 maxVal = Math.max(r, g, b),
29 delta = maxVal - minVal,
40 r: (((maxVal - r) / 6) + (delta / 2)) / delta,
41 g: (((maxVal - g) / 6) + (delta / 2)) / delta,
42 b: (((maxVal - b) / 6) + (delta / 2)) / delta
45 h = deltaRgb.b - deltaRgb.g;
46 } else if (g == maxVal) {
47 h = (1 / 3) + deltaRgb.r - deltaRgb.b;
48 } else if (b == maxVal) {
49 h = (2 / 3) + deltaRgb.g - deltaRgb.r;
51 //handle edge cases for hue
67 hsvToRgb : function(hsv) {
71 r, g, b, rd = Math.round;
80 v2 = v * (1 - s * (vh - vi)),
81 v3 = v * (1 - s * (1 - (vh - vi)));
85 r = v; g = v3; b = v1;
88 r = v2; g = v; b = v1;
91 r = v1; g = v; b = v3;
94 r = v1; g = v2; b = v;
97 r = v3; g = v1; b = v;
100 r = v; g = v1; b = v2;
108 //Generic number interpolator
109 var delta = function(x, y, a, b, theta) {
110 return a + (b - a) * (y - theta) / (y - x);
112 //Add renderer methods.
113 Ext.apply(Renderers, {
114 color: function(fieldName, minColor, maxColor, minValue, maxValue) {
115 var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
116 minColorMatch = minColor.match(re),
117 maxColorMatch = maxColor.match(re),
118 interpolate = function(theta) {
119 return [ delta(minValue, maxValue, minColor[0], maxColor[0], theta),
120 delta(minValue, maxValue, minColor[1], maxColor[1], theta),
121 delta(minValue, maxValue, minColor[2], maxColor[2], theta) ];
123 minColor = ColorManager.rgbToHsv([ +minColorMatch[1], +minColorMatch[2], +minColorMatch[3] ]);
124 maxColor = ColorManager.rgbToHsv([ +maxColorMatch[1], +maxColorMatch[2], +maxColorMatch[3] ]);
125 //Return the renderer
126 return function(sprite, record, attr, index, store) {
127 var value = +record.get(fieldName),
128 rgb = ColorManager.hsvToRgb(interpolate(value)),
129 rgbString = 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')';
130 return Ext.apply(attr, {
136 grayscale: function(fieldName, minColor, maxColor, minValue, maxValue) {
137 var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
138 minColorMatch = minColor.match(re),
139 maxColorMatch = maxColor.match(re),
140 interpolate = function(theta) {
141 var ans = delta(minValue, maxValue, +minColorMatch[1], +maxColorMatch[1], theta) >> 0;
142 return [ ans, ans, ans ];
144 //Return the renderer
145 return function(sprite, record, attr, index, store) {
146 var value = +record.get(fieldName),
147 rgb = interpolate(value),
148 rgbString = 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')';
150 return Ext.apply(attr, {
152 strokeFill: 'rgb(0, 0, 0)'
157 radius: function(fieldName, minRadius, maxRadius, minValue, maxValue) {
158 var interpolate = function(theta) {
159 return delta(minValue, maxValue, minRadius, maxRadius, theta);
161 //Return the renderer
162 return function(sprite, record, attr, index, store) {
163 var value = +record.get(fieldName),
164 radius = interpolate(value);
166 return Ext.apply(attr, {
175 Ext.onReady(function () {
176 //current renderer configuration
177 var rendererConfiguration = {
181 colorFrom: 'rgb(250, 20, 20)',
182 colorTo: 'rgb(127, 0, 240)',
184 scaleFrom: 'rgb(20, 20, 20)',
185 scaleTo: 'rgb(220, 220, 220)',
189 //update the visualization with the new renderer configuration
191 var chart = Ext.getCmp('chartCmp'),
192 series = chart.series.items,
194 rc = rendererConfiguration,
195 color, grayscale, radius, s;
197 for(var i = 0; i < len; i++) {
199 s.xField = rc.xField;
200 s.yField = rc.yField;
201 color = rc.color? Renderers.color(rc.color, rc.colorFrom, rc.colorTo, 0, 100) : function(a, b, attr) { return attr; };
202 grayscale = rc.grayscale? Renderers.grayscale(rc.grayscale, rc.scaleFrom, rc.scaleTo, 0, 100) : function(a, b, attr) { return attr; };
203 radius = rc.radius? Renderers.radius(rc.radius, 10, rc.radiusSize, 0, 100) : function(a, b, attr) { return attr; };
204 s.renderer = function(sprite, record, attr, index, store) {
205 return radius(sprite, record, grayscale(sprite, record, color(sprite, record, attr, index, store), index, store), index, store);
210 //form selection callbacks/handlers.
211 var xAxisHandler = function(elem) {
212 var xField = elem.text;
213 rendererConfiguration.xField = xField;
217 var yAxisHandler = function(elem) {
218 var yField = elem.text;
219 rendererConfiguration.yField = yField;
223 var colorVariableHandler = function(elem) {
224 var color = elem.text;
225 rendererConfiguration.color = color;
226 rendererConfiguration.grayscale = false;
230 var grayscaleVariableHandler = function(elem) {
231 var color = elem.text;
232 rendererConfiguration.grayscale = color;
233 rendererConfiguration.color = false;
237 var scaleFromHandler = function(elem) {
238 var from = elem.text;
239 rendererConfiguration.scaleFrom = from;
243 var scaleToHandler = function(elem) {
245 rendererConfiguration.scaleTo = to;
249 var colorFromHandler = function(elem) {
250 var from = elem.text;
251 rendererConfiguration.colorFrom = from;
255 var colorToHandler = function(elem) {
257 rendererConfiguration.colorTo = to;
261 var radiusHandler = function(elem) {
262 var radius = elem.text;
263 rendererConfiguration.radius = radius;
267 var radiusSizeHandler = function(elem) {
268 var radius = elem.text;
269 rendererConfiguration.radiusSize = parseInt(radius, 10);
273 var xAxisMenu = Ext.create('Ext.menu.Menu', {
277 handler: xAxisHandler,
283 handler: xAxisHandler,
289 handler: xAxisHandler,
295 var yAxisMenu = Ext.create('Ext.menu.Menu', {
299 handler: yAxisHandler,
305 handler: yAxisHandler,
311 handler: yAxisHandler,
317 var colorMenu = Ext.create('Ext.menu.Menu', {
319 items: [ { text: 'data1', handler: colorVariableHandler, checked: false, group: 'color' },
320 { text: 'data2', handler: colorVariableHandler, checked: false, group: 'color' },
321 { text: 'data3', handler: colorVariableHandler, checked: false, group: 'color' },
322 { text: 'Color From',
324 items: [{ text: 'rgb(250, 20, 20)', handler: colorToHandler, checked: true, group: 'colorrange' },
325 { text: 'rgb(20, 250, 20)', handler: colorToHandler, checked: false, group: 'colorrange' },
326 { text: 'rgb(20, 20, 250)', handler: colorToHandler, checked: false, group: 'colorrange' },
327 { text: 'rgb(127, 0, 240)', handler: colorFromHandler, checked: false, group: 'colorrange' },
328 { text: 'rgb(213, 70, 121)', handler: colorToHandler, checked: false, group: 'colorrange' },
329 { text: 'rgb(44, 153, 201)', handler: colorFromHandler, checked: false, group: 'colorrange' },
330 { text: 'rgb(146, 6, 157)', handler: colorFromHandler, checked: false, group: 'colorrange' },
331 { text: 'rgb(49, 149, 0)', handler: colorFromHandler, checked: false, group: 'colorrange' },
332 { text: 'rgb(249, 153, 0)', handler: colorFromHandler, checked: false, group: 'colorrange' }]
337 items: [{ text: 'rgb(250, 20, 20)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
338 { text: 'rgb(20, 250, 20)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
339 { text: 'rgb(20, 20, 250)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
340 { text: 'rgb(127, 0, 220)', handler: colorFromHandler, checked: true, group: 'tocolorrange' },
341 { text: 'rgb(213, 70, 121)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
342 { text: 'rgb(44, 153, 201)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
343 { text: 'rgb(146, 6, 157)' , handler: colorToHandler, checked: false, group: 'tocolorrange' },
344 { text: 'rgb(49, 149, 0)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
345 { text: 'rgb(249, 153, 0)', handler: colorToHandler, checked: false, group: 'tocolorrange' }]
351 var grayscaleMenu = Ext.create('Ext.menu.Menu', {
353 items: [ { text: 'data1', handler: grayscaleVariableHandler, checked: false, group: 'gs' },
354 { text: 'data2', handler: grayscaleVariableHandler, checked: false, group: 'gs' },
355 { text: 'data3', handler: grayscaleVariableHandler, checked: false, group: 'gs' },
356 { text: 'Scale From',
358 items: [{ text: 'rgb(20, 20, 20)', handler: scaleFromHandler, checked: true, group: 'gsrange' },
359 { text: 'rgb(80, 80, 80)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
360 { text: 'rgb(120, 120, 120)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
361 { text: 'rgb(180, 180, 180)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
362 { text: 'rgb(220, 220, 220)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
363 { text: 'rgb(250, 250, 250)', handler: scaleFromHandler, checked: false, group: 'gsrange' }]
368 items: [{ text: 'rgb(20, 20, 20)', handler: scaleToHandler, checked: false, group: 'togsrange' },
369 { text: 'rgb(80, 80, 80)', handler: scaleToHandler, checked: false, group: 'togsrange' },
370 { text: 'rgb(120, 120, 120)', handler: scaleToHandler, checked: false, group: 'togsrange' },
371 { text: 'rgb(180, 180, 180)', handler: scaleToHandler, checked: false, group: 'togsrange' },
372 { text: 'rgb(220, 220, 220)', handler: scaleToHandler, checked: true, group: 'togsrange' },
373 { text: 'rgb(250, 250, 250)', handler: scaleToHandler, checked: false, group: 'togsrange' }]
379 var radiusMenu = Ext.create('Ext.menu.Menu', {
382 overflow: 'visible' // For the Combo popup
384 items: [ { text: 'data1', handler: radiusHandler, checked: false, group: 'radius' },
385 { text: 'data2', handler: radiusHandler, checked: false, group: 'radius' },
386 { text: 'data3', handler: radiusHandler, checked: false, group: 'radius' },
387 { text: 'Max Radius',
389 items: [{ text: '20', handler: radiusSizeHandler, checked: false, group: 'sradius' },
390 { text: '30', handler: radiusSizeHandler, checked: false, group: 'sradius' },
391 { text: '40', handler: radiusSizeHandler, checked: false, group: 'sradius' },
392 { text: '50', handler: radiusSizeHandler, checked: true, group: 'sradius' },
393 { text: '60', handler: radiusSizeHandler, checked: false, group: 'sradius' }]
399 var win = Ext.create('Ext.Window', {
406 title: 'Scatter Chart Renderer',
407 renderTo: Ext.getBody(),
412 handler: function() {
413 store1.loadData(generateData());
417 text: 'Select X Axis',
421 text: 'Select Y Axis',
426 text: 'Select Color',
430 text: 'Select Grayscale',
434 text: 'Select Radius',
441 style: 'background:#fff',