3

在使用 Dojo 的图形库时,我有一个蜘蛛图,定义如下:

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

我为调用的数组的每个成员添加了一个系列,presets并使用了一个可选择的图例,让用户可以根据需要打开或关闭它们。但是,我在文档中似乎找不到的是如何在未选择、不可见的状态下开始一个系列?我最理想的做法是限制页面加载时可见的系列数量,因为在某些情况下,我有多达 14 个预设,而且在用户取消选择一堆之前,它看起来一团糟。因此,我希望在开始时隐藏前 5 个以上的每个预设。

这是我敲过的一个粗略的小提琴来演示。我想要的是在第一次显示情节时取消选择一些系列。

更新:我在添加我的系列后尝试添加这个:

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

哪个有效,但似乎非常脆弱。如果他们更改分配给复选框的类,它将中断。此外,它禁止我使用一组以上的 dojo 复选框,因为我没有很好的方法来区分它们。SelectableLegend(注意,由dijit_form_CheckBox_0,等添加的复选框的 IDdijit_form_CheckBox_1也没有提供有关它们相关内容的有用信息)。我想我也许可以使用图例占位符 div 作为选择后代复选框的一种方式,但似乎 Dojo 完全用表格替换了占位符。

4

4 回答 4

1

dojox/charting/Series 有一个名为dirty 的属性,根据API 文档,它是一个“指示此元素是否需要呈现的标志”。

或者,如果您要限制某些系列的显示,您可以编写一个单独的界面来添加它们。例如,循环前 5 个。然后创建一个选择框或复选框列表,其中包含所有条目和一个调用 chart.addSeries 的 onchange 事件。

如果用户不再希望显示它,保留对您创建的每个系列的引用将允许您稍后在其上调用 destroy() 或 destroyRecursive()。

因此,虽然理想情况下您可以切换这些系列的显示,但最坏的情况是您只是根据一些用户输入添加、销毁和读取。

使用模板化小部件将允许您保持此界面和图表紧密链接并支持重用。

顺便说一句,考虑使用“dojo/_base/array”和“dojo/query”代替 jquery

于 2013-02-11T15:32:55.723 回答
1

我查看了 dojo 代码,发现在 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();
          });

切换过程非常复杂,并且基于许多本地属性:

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

我还尝试手动检查和取消选中图例中的 dijit/form/Checkbox,但这在任何情况下都不会触发 _toggle 函数,即使您在图表上执行 render() / fullrender() 也是如此。

考虑到这一点,除了手动触发 onclick 事件之外,似乎没有其他方法可以打开和关闭系列。

为了使您的代码不那么脆弱,您可以使用以下方法手动访问图例中的 Checkbox 小部件:

查询(“.dijitCheckBox”,图例);// 应该提供一个包含小部件的数组。

并触发它们的 onclick 事件。它们在数组中的键号应与添加的系列的顺序相对应...

Dojo 是一个很好的作品,请不要停止使用它!

于 2013-02-12T10:38:13.953 回答
1

我已经更新了你的代码http://jsfiddle.net/92Dzv/18/

这是toggle的关键。

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

选择图例的索引并设置为_cbs

通过这种方式le._cbs[0].id,您将获得复选框的真实 ID(在小部件中),然后使用click()

注意:le来自这里。

var le = new Legend({
                chart: chart,
                horizontal: false
             }, legend);
于 2013-02-12T04:18:16.907 回答
1

我想我明白了!

我找到了另一种访问复选框的方法!这与 dojo 在内部使用的将“切换代码”连接到 onclick 事件的方式相同。首先看一下 SelectableLegend.js(第 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();
          });

看起来他们使用“.dijitCheckBox”类来查找复选框 dom 元素并使用 dojo/connect 连接到它。现在基于此,我做了这个功能:

函数 toggleSeries (legend,num) {

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

dijit.findWidgets(legend.legends[num])[0]._onClick(); }

它不使用任何类定义(因为*)并且它访问 SelectableLegend 中复选框所在的区域。它需要 SelectableLegend 和要停用的系列的编号作为参数。这里是带有此功能的 jsfiddle 示例并用它隐藏您的所有 4 个系列:

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

另请注意 jsfiddle 中的“onDomReady”选项,没有它:在 IE 中不起作用。以及代码中的 ready 函数!

卢西安

于 2013-02-14T00:00:12.030 回答