123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- Ext.require('Ext.chart.*');
- Ext.require(['Ext.Window', 'Ext.fx.target.Sprite', 'Ext.layout.container.Fit', 'Ext.window.MessageBox']);
- var Renderers = {};
- (function() {
- var ColorManager = {
- rgbToHsv: function(rgb) {
- var r = rgb[0] / 255,
- g = rgb[1] / 255,
- b = rgb[2] / 255,
- rd = Math.round,
- minVal = Math.min(r, g, b),
- maxVal = Math.max(r, g, b),
- delta = maxVal - minVal,
- h = 0, s = 0, v = 0,
- deltaRgb;
- v = maxVal;
- if (delta == 0) {
- return [0, 0, v];
- } else {
- s = delta / maxVal;
- deltaRgb = {
- r: (((maxVal - r) / 6) + (delta / 2)) / delta,
- g: (((maxVal - g) / 6) + (delta / 2)) / delta,
- b: (((maxVal - b) / 6) + (delta / 2)) / delta
- };
- if (r == maxVal) {
- h = deltaRgb.b - deltaRgb.g;
- } else if (g == maxVal) {
- h = (1 / 3) + deltaRgb.r - deltaRgb.b;
- } else if (b == maxVal) {
- h = (2 / 3) + deltaRgb.g - deltaRgb.r;
- }
- //handle edge cases for hue
- if (h < 0) {
- h += 1;
- }
- if (h > 1) {
- h -= 1;
- }
- }
- h = rd(h * 360);
- s = rd(s * 100);
- v = rd(v * 100);
- return [h, s, v];
- },
- hsvToRgb : function(hsv) {
- var h = hsv[0] / 360,
- s = hsv[1] / 100,
- v = hsv[2] / 100,
- r, g, b, rd = Math.round;
- if (s == 0) {
- v *= 255;
- return [v, v, v];
- } else {
- var vh = h * 6,
- vi = vh >> 0,
- v1 = v * (1 - s),
- v2 = v * (1 - s * (vh - vi)),
- v3 = v * (1 - s * (1 - (vh - vi)));
- switch(vi) {
- case 0:
- r = v; g = v3; b = v1;
- break;
- case 1:
- r = v2; g = v; b = v1;
- break;
- case 2:
- r = v1; g = v; b = v3;
- break;
- case 3:
- r = v1; g = v2; b = v;
- break;
- case 4:
- r = v3; g = v1; b = v;
- break;
- default:
- r = v; g = v1; b = v2;
- }
- return [rd(r * 255),
- rd(g * 255),
- rd(b * 255)];
- }
- }
- };
- //Generic number interpolator
- var delta = function(x, y, a, b, theta) {
- return a + (b - a) * (y - theta) / (y - x);
- };
- //Add renderer methods.
- Ext.apply(Renderers, {
- color: function(fieldName, minColor, maxColor, minValue, maxValue) {
- var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
- minColorMatch = minColor.match(re),
- maxColorMatch = maxColor.match(re),
- interpolate = function(theta) {
- return [ delta(minValue, maxValue, minColor[0], maxColor[0], theta),
- delta(minValue, maxValue, minColor[1], maxColor[1], theta),
- delta(minValue, maxValue, minColor[2], maxColor[2], theta) ];
- };
- minColor = ColorManager.rgbToHsv([ +minColorMatch[1], +minColorMatch[2], +minColorMatch[3] ]);
- maxColor = ColorManager.rgbToHsv([ +maxColorMatch[1], +maxColorMatch[2], +maxColorMatch[3] ]);
- //Return the renderer
- return function(sprite, record, attr, index, store) {
- var value = +record.get(fieldName),
- rgb = ColorManager.hsvToRgb(interpolate(value)),
- rgbString = 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')';
- return Ext.apply(attr, {
- fill: rgbString
- });
- };
- },
- grayscale: function(fieldName, minColor, maxColor, minValue, maxValue) {
- var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
- minColorMatch = minColor.match(re),
- maxColorMatch = maxColor.match(re),
- interpolate = function(theta) {
- var ans = delta(minValue, maxValue, +minColorMatch[1], +maxColorMatch[1], theta) >> 0;
- return [ ans, ans, ans ];
- };
- //Return the renderer
- return function(sprite, record, attr, index, store) {
- var value = +record.get(fieldName),
- rgb = interpolate(value),
- rgbString = 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')';
- return Ext.apply(attr, {
- fill: rgbString,
- strokeFill: 'rgb(0, 0, 0)'
- });
- };
- },
- radius: function(fieldName, minRadius, maxRadius, minValue, maxValue) {
- var interpolate = function(theta) {
- return delta(minValue, maxValue, minRadius, maxRadius, theta);
- };
- //Return the renderer
- return function(sprite, record, attr, index, store) {
- var value = +record.get(fieldName),
- radius = interpolate(value);
- return Ext.apply(attr, {
- radius: radius,
- size: radius
- });
- };
- }
- });
- })();
- Ext.onReady(function () {
- //current renderer configuration
- var rendererConfiguration = {
- xField: 'data1',
- yField: 'data2',
- color: false,
- colorFrom: 'rgb(250, 20, 20)',
- colorTo: 'rgb(127, 0, 240)',
- scale: false,
- scaleFrom: 'rgb(20, 20, 20)',
- scaleTo: 'rgb(220, 220, 220)',
- radius: false,
- radiusSize: 50
- };
- //update the visualization with the new renderer configuration
- function refresh() {
- var chart = Ext.getCmp('chartCmp'),
- series = chart.series.items,
- len = series.length,
- rc = rendererConfiguration,
- color, grayscale, radius, s;
- for(var i = 0; i < len; i++) {
- s = series[i];
- s.xField = rc.xField;
- s.yField = rc.yField;
- color = rc.color? Renderers.color(rc.color, rc.colorFrom, rc.colorTo, 0, 100) : function(a, b, attr) { return attr; };
- grayscale = rc.grayscale? Renderers.grayscale(rc.grayscale, rc.scaleFrom, rc.scaleTo, 0, 100) : function(a, b, attr) { return attr; };
- radius = rc.radius? Renderers.radius(rc.radius, 10, rc.radiusSize, 0, 100) : function(a, b, attr) { return attr; };
- s.renderer = function(sprite, record, attr, index, store) {
- return radius(sprite, record, grayscale(sprite, record, color(sprite, record, attr, index, store), index, store), index, store);
- };
- }
- chart.redraw();
- }
- //form selection callbacks/handlers.
- var xAxisHandler = function(elem) {
- var xField = elem.text;
- rendererConfiguration.xField = xField;
- refresh();
- };
- var yAxisHandler = function(elem) {
- var yField = elem.text;
- rendererConfiguration.yField = yField;
- refresh();
- };
- var colorVariableHandler = function(elem) {
- var color = elem.text;
- rendererConfiguration.color = color;
- rendererConfiguration.grayscale = false;
- refresh();
- };
- var grayscaleVariableHandler = function(elem) {
- var color = elem.text;
- rendererConfiguration.grayscale = color;
- rendererConfiguration.color = false;
- refresh();
- };
- var scaleFromHandler = function(elem) {
- var from = elem.text;
- rendererConfiguration.scaleFrom = from;
- refresh();
- };
- var scaleToHandler = function(elem) {
- var to = elem.text;
- rendererConfiguration.scaleTo = to;
- refresh();
- };
- var colorFromHandler = function(elem) {
- var from = elem.text;
- rendererConfiguration.colorFrom = from;
- refresh();
- };
- var colorToHandler = function(elem) {
- var to = elem.text;
- rendererConfiguration.colorTo = to;
- refresh();
- };
- var radiusHandler = function(elem) {
- var radius = elem.text;
- rendererConfiguration.radius = radius;
- refresh();
- };
- var radiusSizeHandler = function(elem) {
- var radius = elem.text;
- rendererConfiguration.radiusSize = parseInt(radius, 10);
- refresh();
- };
- var xAxisMenu = Ext.create('Ext.menu.Menu', {
- id: 'xAxisMenu',
- items: [ {
- text: 'data1',
- handler: xAxisHandler,
- checked: true,
- group: 'x'
- },
- {
- text: 'data2',
- handler: xAxisHandler,
- checked: false,
- group: 'x'
- },
- {
- text: 'data3',
- handler: xAxisHandler,
- checked: false,
- group: 'x'
- } ]
- });
- var yAxisMenu = Ext.create('Ext.menu.Menu', {
- id: 'yAxisMenu',
- items: [ {
- text: 'data1',
- handler: yAxisHandler,
- checked: false,
- group: 'y'
- },
- {
- text: 'data2',
- handler: yAxisHandler,
- checked: true,
- group: 'y'
- },
- {
- text: 'data3',
- handler: yAxisHandler,
- checked: false,
- group: 'y'
- } ]
- });
- var colorMenu = Ext.create('Ext.menu.Menu', {
- id: 'colorMenu',
- items: [ { text: 'data1', handler: colorVariableHandler, checked: false, group: 'color' },
- { text: 'data2', handler: colorVariableHandler, checked: false, group: 'color' },
- { text: 'data3', handler: colorVariableHandler, checked: false, group: 'color' },
- { text: 'Color From',
- menu: {
- items: [{ text: 'rgb(250, 20, 20)', handler: colorToHandler, checked: true, group: 'colorrange' },
- { text: 'rgb(20, 250, 20)', handler: colorToHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(20, 20, 250)', handler: colorToHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(127, 0, 240)', handler: colorFromHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(213, 70, 121)', handler: colorToHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(44, 153, 201)', handler: colorFromHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(146, 6, 157)', handler: colorFromHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(49, 149, 0)', handler: colorFromHandler, checked: false, group: 'colorrange' },
- { text: 'rgb(249, 153, 0)', handler: colorFromHandler, checked: false, group: 'colorrange' }]
- }
- },
- { text: 'Color To',
- menu: {
- items: [{ text: 'rgb(250, 20, 20)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(20, 250, 20)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(20, 20, 250)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(127, 0, 220)', handler: colorFromHandler, checked: true, group: 'tocolorrange' },
- { text: 'rgb(213, 70, 121)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(44, 153, 201)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(146, 6, 157)' , handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(49, 149, 0)', handler: colorToHandler, checked: false, group: 'tocolorrange' },
- { text: 'rgb(249, 153, 0)', handler: colorToHandler, checked: false, group: 'tocolorrange' }]
- }
- }
- ]
- });
- var grayscaleMenu = Ext.create('Ext.menu.Menu', {
- id: 'grayscaleMenu',
- items: [ { text: 'data1', handler: grayscaleVariableHandler, checked: false, group: 'gs' },
- { text: 'data2', handler: grayscaleVariableHandler, checked: false, group: 'gs' },
- { text: 'data3', handler: grayscaleVariableHandler, checked: false, group: 'gs' },
- { text: 'Scale From',
- menu: {
- items: [{ text: 'rgb(20, 20, 20)', handler: scaleFromHandler, checked: true, group: 'gsrange' },
- { text: 'rgb(80, 80, 80)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
- { text: 'rgb(120, 120, 120)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
- { text: 'rgb(180, 180, 180)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
- { text: 'rgb(220, 220, 220)', handler: scaleFromHandler, checked: false, group: 'gsrange' },
- { text: 'rgb(250, 250, 250)', handler: scaleFromHandler, checked: false, group: 'gsrange' }]
- }
- },
- { text: 'Scale To',
- menu: {
- items: [{ text: 'rgb(20, 20, 20)', handler: scaleToHandler, checked: false, group: 'togsrange' },
- { text: 'rgb(80, 80, 80)', handler: scaleToHandler, checked: false, group: 'togsrange' },
- { text: 'rgb(120, 120, 120)', handler: scaleToHandler, checked: false, group: 'togsrange' },
- { text: 'rgb(180, 180, 180)', handler: scaleToHandler, checked: false, group: 'togsrange' },
- { text: 'rgb(220, 220, 220)', handler: scaleToHandler, checked: true, group: 'togsrange' },
- { text: 'rgb(250, 250, 250)', handler: scaleToHandler, checked: false, group: 'togsrange' }]
- }
- }
- ]
- });
- var radiusMenu = Ext.create('Ext.menu.Menu', {
- id: 'radiusMenu',
- style: {
- overflow: 'visible' // For the Combo popup
- },
- items: [ { text: 'data1', handler: radiusHandler, checked: false, group: 'radius' },
- { text: 'data2', handler: radiusHandler, checked: false, group: 'radius' },
- { text: 'data3', handler: radiusHandler, checked: false, group: 'radius' },
- { text: 'Max Radius',
- menu: {
- items: [{ text: '20', handler: radiusSizeHandler, checked: false, group: 'sradius' },
- { text: '30', handler: radiusSizeHandler, checked: false, group: 'sradius' },
- { text: '40', handler: radiusSizeHandler, checked: false, group: 'sradius' },
- { text: '50', handler: radiusSizeHandler, checked: true, group: 'sradius' },
- { text: '60', handler: radiusSizeHandler, checked: false, group: 'sradius' }]
- }
- }
- ]
- });
- var chart = Ext.create('Ext.chart.Chart', {
- id: 'chartCmp',
- xtype: 'chart',
- style: 'background:#fff',
- animate: true,
- store: store1,
- axes: false,
- insetPadding: 50,
- series: [{
- type: 'scatter',
- axis: false,
- xField: 'data1',
- yField: 'data2',
- color: '#ccc',
- markerConfig: {
- type: 'circle',
- radius: 20,
- size: 20
- }
- }]
- });
-
- var win = Ext.create('Ext.Window', {
- width: 800,
- height: 600,
- minHeight: 400,
- minWidth: 650,
- hidden: false,
- maximizable: true,
- title: 'Scatter Chart Renderer',
- renderTo: Ext.getBody(),
- layout: 'fit',
- tbar: [{
- text: 'Save Chart',
- handler: function() {
- Ext.MessageBox.confirm('Confirm Download', 'Would you like to download the chart as an image?', function(choice){
- if(choice == 'yes'){
- chart.save({
- type: 'image/png'
- });
- }
- });
- }
- },
- {
- text: 'Reload Data',
- handler: function() {
- store1.loadData(generateData());
- }
- },
- {
- text: 'Select X Axis',
- menu: xAxisMenu
- },
- {
- text: 'Select Y Axis',
- menu: yAxisMenu
- },
- {
- text: 'Select Color',
- menu: colorMenu
- },
- {
- text: 'Select Grayscale',
- menu: grayscaleMenu
- },
- {
- text: 'Select Radius',
- menu: radiusMenu
- }
- ],
- items: chart
- });
- });
|