【问题标题】:Draw an arbitrary number of lines on a protovis chart在 protovis 图表上绘制任意数量的线
【发布时间】:2015-08-18 11:55:45
【问题描述】:

我的目标

我正在尝试在 protovis 中的图表中添加任意数量的垂直线。给定一个 x 截距值数组,我想遍历这个数组并为每个截距值画一条垂直线。现在,我可以画出固定数量的线条,但无法概括。

我做了什么

我制作了一个jsfiddle,展示了如何将固定数量的线添加到图表中,并在下面复制了该代码。在这里,我通过显式编码x_value0x_value1 添加了两行代码。在代码中,有两段相关的 protovis 代码,我标记为 Section ASection BSection A 是一个 protovis 函数,它定义了线的绘制位置,Section B 调用这些函数。

// X intercept values hard coded
var x_value0 = 30;
var x_value1 = 70;

new pvc.MetricDotChart({
    canvas:   "cccExample",
    width:    500,
    height:   400,
    axisGrid: true,
    axisZeroLine: false,
    selectable: true,

    extensionPoints: {

        plot_add: function() {
            var panel = new pv.Panel()
                // Quadrant rules above grid, but below dots.
                .zOrder(-1)

                ////
                // Section A Begin
                ////

                // Line 1
                .def('l0', function() {
                    var ccc = this.getContext();
                    var scale = ccc.chart.axes.base.scale;
                    var li = ccc.panel._layoutInfo;
                    return li.paddings.left + scale(x_value0);
                })

                // Line 2
                .def('l1', function() {
                    var ccc = this.getContext();
                    var scale = ccc.chart.axes.base.scale;
                    var li = ccc.panel._layoutInfo;
                    return li.paddings.left + scale(x_value1);
                })

                ////
                // Section A End
                ////

            ;

        ////
        // Section B Begin
        ////   

        // Line 1
            panel
            .add(pv.Rule)
            .top(0)
            .left  (function() { return this.parent.l0();     })
            .height(function() { return this.parent.height(); })
            .width(null)
            ;      

        // Line 2
            panel
            .add(pv.Rule)
            .top(0)
            .left  (function() { return this.parent.l1();     })
            .height(function() { return this.parent.height(); })
            .width(null)
            ;            

        ////
        // Section B End
        ////               

            return panel;      

        }
    }
})

.setData(testLDot2)
.render();  

我想做的是将xvalues 定义为一个数组,然后循环它。我的尝试已经完成了一半。我创建了一个second jsfiddle,我尝试将xvalues 移动到一个数组中。问题是我似乎无法成功地将相关部分包装在 for 循环中。该jsfiddle的代码是:

// X intercept values in an array
var x_values = [30, 60];

new pvc.MetricDotChart({
    canvas:   "cccExample",
    width:    500,
    height:   400,
    axisGrid: true,
    axisZeroLine: false,
    selectable: true,

    extensionPoints: {

        plot_add: function() {
            var panel = new pv.Panel()
                // Quadrant rules above grid, but below dots.
                .zOrder(-1)

                ////
                // Section A Begin - How can I put this inside of a loop?
                ////

                // Line 1
                .def('l0', function() {
                    var ccc = this.getContext();
                    var scale = ccc.chart.axes.base.scale;
                    var li = ccc.panel._layoutInfo;
                    return li.paddings.left + scale(x_values[0]);
                })

                // Line 2
                .def('l1', function() {
                    var ccc = this.getContext();
                    var scale = ccc.chart.axes.base.scale;
                    var li = ccc.panel._layoutInfo;
                    return li.paddings.left + scale(x_values[1]);
                })

                ////
                // Section A End
                ////

            ;

        ////
        // Section B Begin - I'm able to successfully loop this part
        ////   

            for (i = 0; i < x_values.length; i++) {
                // The name of the .def function defined above
                var fn_name = 'this.parent.l' + i + '()';
                // Draw the lines
                    panel
                    .add(pv.Rule)
                    .top(0)
                    .left  (function() { return eval(fn_name);     })
                    .height(function() { return this.parent.height(); })
                    .width(null)
;      

            }

        ////
        // Section B End
        ////               

            return panel;      

        }
    }
})

.setData(testLDot2)
.render();

我可以将 Section B 包装在 for 循环中,并且我想为 Section A 做类似的事情:

for (i = 0; i < x_values.length; i++) {
    .def('l'+i, function() {
        var ccc = this.getContext();
        var scale = ccc.chart.axes.base.scale;
        var li = ccc.panel._layoutInfo;
        return li.paddings.left + scale(x_values[i]);
    })
}

或类似的东西。但问题是 protovis 似乎不允许我在这个 .def 块周围放置任何代码。

我还尝试为 x_values 数组中的每个项目生成一个字符串,其中包含 Section A 函数的定义,然后使用 eval() 在 protovis 代码中调用它,但这并没有到目前为止没有工作。

这里的任何帮助将不胜感激!

编辑 - 更多进展

通过删除Section A 并将该功能移到Section B 中,我似乎已经更接近我想要的了。有关该代码,请参见 my latest jsfiddle。以前,在Section B 中,.left 行调用了Section A 中定义的函数之一。相反,我将该函数的定义移到了 .left 代码行中,如下所示:

////
// Section B Begin
////   

for (var i = 0; i < x_values.length; i++) {
    var x = x_values[i];
    // Lines
    panel
    .add(pv.Rule)
    .top(0)
    .left  (function() {                 
        var ccc = this.parent.getContext();
        var scale = ccc.chart.axes.base.scale;
        var li = ccc.panel._layoutInfo;
        return li.paddings.left + scale(x);                                     
    })
    .height(function() { return this.parent.height(); })
    .width(null)
    ;      
}

现在正在运行,但仍然不太正确:它只绘制x_values 数组中的最后一行并覆盖所有以前的行。有什么想法吗?

【问题讨论】:

    标签: javascript data-visualization protovis pentaho-ctools ccc


    【解决方案1】:

    用下面的代码替换你的循环

    panel
        .add(pv.Rule)
        .data(x_values)
        .top(0)
        .left  (
            function(d) {                 
            this.index * 20 + 15
            var ccc = this.parent.getContext();
            var scale = ccc.chart.axes.base.scale;
            var li = ccc.panel._layoutInfo;
            return li.paddings.left + scale(d);                                     
        })
        .height(function() { return this.parent.height(); })
        .width(null)
        ;     
    

    小提琴http://jsfiddle.net/f9uhzaz9/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多