Hiding the default streak on the spider plot

I have a graph of spiders in using the Dojo graphics library, defined like this:

require([
    "dojox/charting/Chart", 
    "dojox/charting/themes/Claro", 
    "dojox/charting/plot2d/Spider", 
    "dojox/charting/action2d/Tooltip", 
    "dojox/charting/widget/SelectableLegend", 
    "dojox/charting/axis2d/Default"
    ], function (Chart, theme, Spider, Tooltip, Legend, Default) {
        var chart = new Chart(element).setTheme(theme).addPlot("default", {
            type: Spider,
            radius: 200,
            fontColor: "black",
            labelOffset: "-20"
        });
        var colors = ["blue", "red", "green", "yellow", "purple", "orange", "teal", 
                    "maroon", "olive", "lime", "aqua", "fuchsia"];
        $.each(factors, function (index, factor) {
            chart.addAxis(factor.name, {
                 type: Default,
                 min: factor.min,
                 max: factor.max
             });
        });
        $.each(presets, function (pIndex, preset) {
            var data = [];
            $.each(factors, function (fIndex, factor) {
                 data[factor.name] = preset.values[fIndex];
            });
            chart.addSeries(preset.short, data, {
                 fill: colors[pIndex % colors.length]
            });
        });
        new Tooltip(chart, "default");
        chart.render();
        new Legend({
            chart: chart,
            horizontal: false
        }, $(element).next(".legend")[0]);
    });

      

I add a series for each member of the named array presets

and I use a selectable legend that allows the user to turn them on or off as they see fit. However, what I cannot find in the docs is how to start the series in an unselected, invisible state? What I ideally want to do is limit the number of rows visible on page load, because in some cases I have up to 14 presets and it's just a mess until the user selects a bunch. So I would like, say, every preset above the first 5 to be hidden at the start.

Here's a rough fiddle I knocked on to demonstrate. I want some of the series to be canceled when the graph is first displayed.

Update : I tried to add this after adding my series:

var checkboxes = $(".dijitCheckBoxInput").each((index, elem) => {
     if (index > 4) {
         elem.click();
     }
});

      

Which works, but seems very fragile. If they change the class assigned to the checkboxes it will break. Also, it prevents me from using multiple sets of Dojo checkboxes because I don't have a good way to communicate the differences. (Note that the identifiers of the checkboxes added SelectableLegend

are this dijit_form_CheckBox_0

, dijit_form_CheckBox_1

etc., which also does not provide any useful information about what they refer to). I thought I could use the legend separator as a way to select the child checkboxes, but it seems that Dojo is completely replacing the placeholder with a table.

+3


source to share


4 answers


I looked through the dojo code and found the area where shapes are toggled on and off using SelectableLegend.js:

          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();
          });

      

The switching process is very complex and relies on many local attributes:

_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);
        }

      

I tried to also check and uncheck the dijit / form / Checkbox in the legend manually, but that doesn't call the _toggle function anyway, even if you are rendering () / fullrender () on the diagram.



With this in mind, it seems like there is no other way to turn the series on and off other than manually triggering onclick events.

To make your code less fragile, you can manually access the checkbox widgets in the legend using:

query (". dijitCheckBox", legend); // Should deliver an array containing widgets.

and fires an onclick event on them. Their key number in the array must match the order in which the ...

Dojo is a great job, please don't stop working with it!

+1


source


dojox / charting / Series has an attribute called dirty, which according to the docs API is "a flag indicating whether this element should be rendered".

Alternatively, if you restrict the display of some series, you can write a separate interface to add them. For example, go to the first 5. Next, create a select box or checkbox list with all the entries and an onchange event that calls chart.addSeries.

Saving a reference to every series you create will allow you to call destroy () or destroyRecursive () later if the user no longer wants to display it.



So, ideally you can switch the display of these series, the worst senerio is what you just add, destroy and read based on some user input.

By using a templated widget , you can keep this interface and diagram tightly coupled and reusable.

By the way, consider using "dojo / _ base / array" and "dojo / query" instead of jQuery

+1


source


I have updated your code http://jsfiddle.net/92Dzv/18/

Here's the key to Google.

dom.byId(le._cbs[0].id).click();
dom.byId(le._cbs[2].id).click();

      

Choose your legend's index and install _cbs

.

This way le._cbs[0].id

you get the real ID of the checkbox (inside the widget) and then just useclick()

Note: le

came from here.

var le = new Legend({
                chart: chart,
                horizontal: false
             }, legend);

      

+1


source


I think I have it!

I found another way to access checkboxes! Likewise, dojo uses internally to hook up the "toggle code" to the onclick event. Take a look at this first with SelectableLegend.js (Lines 150 - 156):

          //  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();
          });

      

It looks like they are using the ".dijitCheckBox" class to find the dombox checkbox element and connect to it using dojo / connect. Now, based on that, I made this function:

function toggleSeries (legend, num) {

dojo.query ("*", legend.legends [number]) [0] .click ();

dijit.findWidgets (legend.legends [number]) [0] ._ OnClick (); }

It does not use class definitions (due to * ) and it refers to the scopes that the checkboxes are within the SelectableLegend. He needs to select SelectableLegend and the series number that you want to deactivate as parameters. Here's a jsfiddle example with this function and hide all 4 of your series:

http://jsfiddle.net/luciancd/92Dzv/17/

Also notice the "onDomReady" parameter in jsfiddle, without it: doesn't work in IE. And a ready-made function inside the code!

Lucian

+1


source







All Articles