dojox/charting/widget/SelectableLegend.js

  • Provides:

    • dojox.charting.widget.SelectableLegend
  • Requires:

    • dojox.charting.widget.Legend in common
    • dijit.form.CheckBox in common in project dijit
    • dojox.charting.action2d.Highlight in common
  • dojox.charting.widget.SelectableLegend

    • type
      Function
    • chains:
      • dojox.charting.widget.Legend: (prototype)
      • dojox.charting.widget.Legend: (call)
    • summary
      An enhanced chart legend supporting interactive events on data series
      
      theme component
  • dojox.charting.widget.SelectableLegend.outline

    • summary
  • dojox.charting.widget.SelectableLegend.transitionFill

    • summary
  • dojox.charting.widget.SelectableLegend.transitionStroke

    • summary
  • dojox.charting.widget.SelectableLegend.postCreate

    • type
      Function
    • source: [view]
         this.legends = [];
         this.legendAnim = {};
         this.inherited(arguments);
    • summary
  • dojox.charting.widget.SelectableLegend.refresh

    • type
      Function
    • source: [view]
         this.legends = [];
         this.inherited(arguments);
         this._applyEvents();
         new dojox.charting.widget._FocusManager(this);
    • summary
  • dojox.charting.widget.SelectableLegend._addLabel

    • type
      Function
    • parameters:
      • dyn: (typeof )
      • label: (typeof )
    • source: [view]
         this.inherited(arguments);
         // create checkbox
         var legendNodes = dojo.query("td", this.legendBody);
         var currentLegendNode = legendNodes[legendNodes.length - 1];
         this.legends.push(currentLegendNode);
         var checkbox = new dijit.form.CheckBox({checked: true});
         dojo.place(checkbox.domNode, currentLegendNode, "first");
         // connect checkbox and existed label
         var label = dojo.query("label", currentLegendNode)[0];
         dojo.attr(label, "for", checkbox.id);
    • summary
  • dojox.charting.widget.SelectableLegend._applyEvents

    • type
      Function
    • source: [view]
         dojo.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 = dojo.query(".dijitCheckBox", legend)[0];
          dojo.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 = dojo.query(".dojoxLegendIcon", legend)[0],
           iconShape = this._getFilledShape(this._surfaces[i].children);
          dojo.forEach(["onmouseenter", "onmouseleave"], function(event){
           dojo.connect(legendIcon, event, this, function(e){
            this._highlight(e, iconShape, shapes, i, legend.vanished, originalDyn, seriesName, plotName);
           });
          }, this);
         },this);
    • summary
      Apply click-event on checkbox and hover-event on legend icon,
      highlight data series or toggle it.
  • dojox.charting.widget.SelectableLegend._toggle

    • type
      Function
    • parameters:
      • shapes: (typeof )
      • index: (typeof )
      • isOff: (typeof )
      • dyn: (typeof )
      • seriesName: (typeof )
      • plotName: (typeof )
    • source: [view]
         dojo.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 dojo.Color)){
            dojox.gfx.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);
    • summary
  • dojox.charting.widget.SelectableLegend._highlight

    • type
      Function
    • parameters:
      • e: (typeof )
      • iconShape: (typeof )
      • shapes: (typeof )
      • index: (typeof )
      • isOff: (typeof )
      • dyn: (typeof )
      • seriesName: (typeof )
      • plotName: (typeof )
    • source: [view]
         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
          dojo.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);
          });
         }
    • summary
  • dojox.charting.widget.SelectableLegend._getAnim

    • type
      Function
    • parameters:
      • plotName: (typeof )
    • source: [view]
         if(!this.legendAnim[plotName]){
          this.legendAnim[plotName] = new dojox.charting.action2d.Highlight(this.chart, plotName);
         }
         return this.legendAnim[plotName];
    • summary
  • dojox.charting.widget.SelectableLegend._getTransitionFill

    • type
      Function
    • parameters:
      • plotName: (typeof )
    • source: [view]
      dojo.provide("dojox.charting.widget.SelectableLegend");


      dojo.require("dojox.charting.widget.Legend");
      dojo.require("dijit.form.CheckBox");
      dojo.require("dojox.charting.action2d.Highlight");


      (function(){
       var df = dojox.lang.functional;

       
       dojo.declare("dojox.charting.widget.SelectableLegend", [dojox.charting.widget.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 dojox.charting.widget._FocusManager(this);
        },
        _addLabel: function(dyn, label){
         this.inherited(arguments);
         // create checkbox
         var legendNodes = dojo.query("td", this.legendBody);
         var currentLegendNode = legendNodes[legendNodes.length - 1];
         this.legends.push(currentLegendNode);
         var checkbox = new dijit.form.CheckBox({checked: true});
         dojo.place(checkbox.domNode, currentLegendNode, "first");
         // connect checkbox and existed label
         var label = dojo.query("label", currentLegendNode)[0];
         dojo.attr(label, "for", checkbox.id);
        },
        _applyEvents: function(){
         // summary:
         //  Apply click-event on checkbox and hover-event on legend icon,
         //  highlight data series or toggle it.

         
         dojo.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 = dojo.query(".dijitCheckBox", legend)[0];
          dojo.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 = dojo.query(".dojoxLegendIcon", legend)[0],
           iconShape = this._getFilledShape(this._surfaces[i].children);
          dojo.forEach(["onmouseenter", "onmouseleave"], function(event){
           dojo.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){
         dojo.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 dojo.Color)){
            dojox.gfx.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
          dojo.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 dojox.charting.action2d.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;
    • summary
  • dojox.charting.widget.SelectableLegend._getFilledShape

    • type
      Function
    • parameters:
      • shapes: (typeof )
    • source: [view]
         var i = 0;
         while(shapes[i]){
          if(shapes[i].getFill())return shapes[i];
          i++;
         }
    • summary
      Get filled shape in legend icon which would be highlighted when hovered
  • dojox.charting.widget.SelectableLegend._isPie

    • type
      Function
    • source: [view]
         return this.chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie";
    • summary
  • dojox.charting.widget.SelectableLegend.legends

    • summary
  • dojox.charting.widget.SelectableLegend.legendAnim

    • summary
  • dojox.charting.widget._FocusManager

    • type
      Function
    • summary
      It will take legend as a tab stop, and using
      cursor keys to navigate labels within the legend.
    • parameters:
      • legend: (typeof )
    • source: [view]
         this.legend = legend;
         this.index = 0;
         this.horizontalLength = this._getHrizontalLength();
         dojo.forEach(legend.legends, function(item, i){
          if(i > 0){
           dojo.query("input", item).attr("tabindex", -1);
          }
         });
         this.firstLabel = dojo.query("input", legend.legends[0])[0];
         dojo.connect(this.firstLabel, "focus", this, function(){this.legend.active = true;});
         dojo.connect(this.legend.legendNode, "keydown", this, "_onKeyEvent");
  • dojox.charting.widget._FocusManager._getHrizontalLength

    • type
      Function
    • source: [view]
         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;
         }
    • summary
  • dojox.charting.widget._FocusManager._onKeyEvent

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
      dojo.provide("dojox.charting.widget.SelectableLegend");


      dojo.require("dojox.charting.widget.Legend");
      dojo.require("dijit.form.CheckBox");
      dojo.require("dojox.charting.action2d.Highlight");


      (function(){
       var df = dojox.lang.functional;

       
       dojo.declare("dojox.charting.widget.SelectableLegend", [dojox.charting.widget.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 dojox.charting.widget._FocusManager(this);
        },
        _addLabel: function(dyn, label){
         this.inherited(arguments);
         // create checkbox
         var legendNodes = dojo.query("td", this.legendBody);
         var currentLegendNode = legendNodes[legendNodes.length - 1];
         this.legends.push(currentLegendNode);
         var checkbox = new dijit.form.CheckBox({checked: true});
         dojo.place(checkbox.domNode, currentLegendNode, "first");
         // connect checkbox and existed label
         var label = dojo.query("label", currentLegendNode)[0];
         dojo.attr(label, "for", checkbox.id);
        },
        _applyEvents: function(){
         // summary:
         //  Apply click-event on checkbox and hover-event on legend icon,
         //  highlight data series or toggle it.

         
         dojo.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 = dojo.query(".dijitCheckBox", legend)[0];
          dojo.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 = dojo.query(".dojoxLegendIcon", legend)[0],
           iconShape = this._getFilledShape(this._surfaces[i].children);
          dojo.forEach(["onmouseenter", "onmouseleave"], function(event){
           dojo.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){
         dojo.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 dojo.Color)){
            dojox.gfx.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
          dojo.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 dojox.charting.action2d.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;
       }
       dojo.declare("dojox.charting.widget._FocusManager", 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();
         dojo.forEach(legend.legends, function(item, i){
          if(i > 0){
           dojo.query("input", item).attr("tabindex", -1);
          }
         });
         this.firstLabel = dojo.query("input", legend.legends[0])[0];
         dojo.connect(this.firstLabel, "focus", this, function(){this.legend.active = true;});
         dojo.connect(this.legend.legendNode, "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 == dojo.keys.TAB){
          this.legend.active = false;
          return;
         }
         // handle with arrow keys
         var max = this.legend.legends.length;
         switch(e.keyCode){
          case dojo.keys.LEFT_ARROW:
           this.index--;
           if(this.index < 0){
            this.index += max;
           }
           break;
          case dojo.keys.RIGHT_ARROW:
           this.index++;
           if(this.index >= max){
            this.index -= max;
           }
           break;
          case dojo.keys.UP_ARROW:
           if(this.index - this.horizontalLength >= 0){
            this.index -= this.horizontalLength;
           }
           break;
          case dojo.keys.DOWN_ARROW:
           if(this.index + this.horizontalLength < max){
            this.index += this.horizontalLength;
           }
           break;
          default:
           return;
         }
         this._moveToFocus();
         dojo.stopEvent(e);
    • summary
  • dojox.charting.widget._FocusManager._moveToFocus

    • type
      Function
    • source: [view]
         dojo.query("input", this.legend.legends[this.index])[0].focus();
    • summary
  • dojox.charting.widget._FocusManager.legend.active

    • summary
  • dojox.charting.widget._FocusManager.legend

    • summary
  • dojox.charting.widget._FocusManager.index

    • summary
  • dojox.charting.widget._FocusManager.horizontalLength

    • summary
  • dojox.charting.widget._FocusManager.firstLabel

    • summary
  • dojox.charting.widget

    • type
      Object
    • summary
  • dojox.charting

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary