diff options
Diffstat (limited to 'js/dojo-1.7.2/dojox/charting/widget/SelectableLegend.js')
| -rw-r--r-- | js/dojo-1.7.2/dojox/charting/widget/SelectableLegend.js | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/charting/widget/SelectableLegend.js b/js/dojo-1.7.2/dojox/charting/widget/SelectableLegend.js new file mode 100644 index 0000000..2836679 --- /dev/null +++ b/js/dojo-1.7.2/dojox/charting/widget/SelectableLegend.js @@ -0,0 +1,245 @@ +//>>built +define("dojox/charting/widget/SelectableLegend", ["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/query", "dojo/_base/html", + "dojo/_base/connect", "dojo/_base/Color", "./Legend", "dijit/form/CheckBox", "../action2d/Highlight", + "dojox/lang/functional", "dojox/gfx/fx", "dojo/keys", "dojo/_base/event", "dojo/dom-construct", + "dojo/dom-prop"], + function(lang, arrayUtil, declare, query, html, hub, Color, Legend, CheckBox, + Highlight, df, fx, keys, event, dom, domProp){ +/*===== +var Legend = dojox.charting.widget.Legend; +=====*/ + var FocusManager = declare(null, { + // summary: + // It will take legend as a tab stop, and using + // cursor keys to navigate labels within the legend. + constructor: function(legend){ + this.legend = legend; + this.index = 0; + this.horizontalLength = this._getHrizontalLength(); + arrayUtil.forEach(legend.legends, function(item, i){ + if(i > 0){ + query("input", item).attr("tabindex", -1); + } + }); + this.firstLabel = query("input", legend.legends[0])[0]; + hub.connect(this.firstLabel, "focus", this, function(){this.legend.active = true;}); + hub.connect(this.legend.domNode, "keydown", this, "_onKeyEvent"); + }, + _getHrizontalLength: function(){ + var horizontal = this.legend.horizontal; + if(typeof horizontal == "number"){ + return Math.min(horizontal, this.legend.legends.length); + }else if(!horizontal){ + return 1; + }else{ + return this.legend.legends.length; + } + }, + _onKeyEvent: function(e){ + // if not focused + if(!this.legend.active){ + return; + } + // lose focus + if(e.keyCode == keys.TAB){ + this.legend.active = false; + return; + } + // handle with arrow keys + var max = this.legend.legends.length; + switch(e.keyCode){ + case keys.LEFT_ARROW: + this.index--; + if(this.index < 0){ + this.index += max; + } + break; + case keys.RIGHT_ARROW: + this.index++; + if(this.index >= max){ + this.index -= max; + } + break; + case keys.UP_ARROW: + if(this.index - this.horizontalLength >= 0){ + this.index -= this.horizontalLength; + } + break; + case keys.DOWN_ARROW: + if(this.index + this.horizontalLength < max){ + this.index += this.horizontalLength; + } + break; + default: + return; + } + this._moveToFocus(); + Event.stop(e); + }, + _moveToFocus: function(){ + query("input", this.legend.legends[this.index])[0].focus(); + } + }); + + declare("dojox.charting.widget.SelectableLegend", Legend, { + // summary: + // An enhanced chart legend supporting interactive events on data series + + // theme component + outline: false, // outline of vanished data series + transitionFill: null, // fill of deselected data series + transitionStroke: null, // stroke of deselected data series + + postCreate: function(){ + this.legends = []; + this.legendAnim = {}; + this.inherited(arguments); + }, + refresh: function(){ + this.legends = []; + this.inherited(arguments); + this._applyEvents(); + new FocusManager(this); + }, + _addLabel: function(dyn, label){ + this.inherited(arguments); + // create checkbox + var legendNodes = query("td", this.legendBody); + var currentLegendNode = legendNodes[legendNodes.length - 1]; + this.legends.push(currentLegendNode); + var checkbox = new CheckBox({checked: true}); + dom.place(checkbox.domNode, currentLegendNode, "first"); + // connect checkbox and existed label + var label = query("label", currentLegendNode)[0]; + domProp.set(label, "for", checkbox.id); + }, + _applyEvents: function(){ + // summary: + // Apply click-event on checkbox and hover-event on legend icon, + // highlight data series or toggle it. + // if the chart has not yet been refreshed it will crash here (targetData.group == null) + if(this.chart.dirty){ + return; + } + arrayUtil.forEach(this.legends, function(legend, i){ + var targetData, shapes = [], plotName, seriesName; + if(this._isPie()){ + targetData = this.chart.stack[0]; + shapes.push(targetData.group.children[i]); + plotName = targetData.name; + seriesName = this.chart.series[0].name; + }else{ + targetData = this.chart.series[i]; + shapes = targetData.group.children; + plotName = targetData.plot; + seriesName = targetData.name; + } + var originalDyn = { + fills : df.map(shapes, "x.getFill()"), + strokes: df.map(shapes, "x.getStroke()") + }; + // toggle action + var legendCheckBox = query(".dijitCheckBox", legend)[0]; + hub.connect(legendCheckBox, "onclick", this, function(e){ + this._toggle(shapes, i, legend.vanished, originalDyn, seriesName, plotName); + legend.vanished = !legend.vanished; + e.stopPropagation(); + }); + + // highlight action + var legendIcon = query(".dojoxLegendIcon", legend)[0], + iconShape = this._getFilledShape(this._surfaces[i].children); + arrayUtil.forEach(["onmouseenter", "onmouseleave"], function(event){ + hub.connect(legendIcon, event, this, function(e){ + this._highlight(e, iconShape, shapes, i, legend.vanished, originalDyn, seriesName, plotName); + }); + }, this); + },this); + }, + _toggle: function(shapes, index, isOff, dyn, seriesName, plotName){ + arrayUtil.forEach(shapes, function(shape, i){ + var startFill = dyn.fills[i], + endFill = this._getTransitionFill(plotName), + startStroke = dyn.strokes[i], + endStroke = this.transitionStroke; + if(startFill){ + if(endFill && (typeof startFill == "string" || startFill instanceof Color)){ + fx.animateFill({ + shape: shape, + color: { + start: isOff ? endFill : startFill, + end: isOff ? startFill : endFill + } + }).play(); + }else{ + shape.setFill(isOff ? startFill : endFill); + } + } + if(startStroke && !this.outline){ + shape.setStroke(isOff ? startStroke : endStroke); + } + }, this); + }, + _highlight: function(e, iconShape, shapes, index, isOff, dyn, seriesName, plotName){ + if(!isOff){ + var anim = this._getAnim(plotName), + isPie = this._isPie(), + type = formatEventType(e.type); + // highlight the label icon, + var label = { + shape: iconShape, + index: isPie ? "legend" + index : "legend", + run: {name: seriesName}, + type: type + }; + anim.process(label); + // highlight the data items + arrayUtil.forEach(shapes, function(shape, i){ + shape.setFill(dyn.fills[i]); + var o = { + shape: shape, + index: isPie ? index : i, + run: {name: seriesName}, + type: type + }; + anim.duration = 100; + anim.process(o); + }); + } + }, + _getAnim: function(plotName){ + if(!this.legendAnim[plotName]){ + this.legendAnim[plotName] = new Highlight(this.chart, plotName); + } + return this.legendAnim[plotName]; + }, + _getTransitionFill: function(plotName){ + // Since series of stacked charts all start from the base line, + // fill the "front" series with plotarea color to make it disappear . + if(this.chart.stack[this.chart.plots[plotName]].declaredClass.indexOf("dojox.charting.plot2d.Stacked") != -1){ + return this.chart.theme.plotarea.fill; + } + return null; + }, + _getFilledShape: function(shapes){ + // summary: + // Get filled shape in legend icon which would be highlighted when hovered + var i = 0; + while(shapes[i]){ + if(shapes[i].getFill())return shapes[i]; + i++; + } + }, + _isPie: function(){ + return this.chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie"; + } + }); + + function formatEventType(type){ + if(type == "mouseenter")return "onmouseover"; + if(type == "mouseleave")return "onmouseout"; + return "on" + type; + } + + return dojox.charting.widget.SelectableLegend; +}); |
