【问题标题】:One slider, two graphs, with Rickshaw and D3.js一个滑块,两个图表,带有 Rickshaw 和 D3.js
【发布时间】:2012-11-16 00:14:30
【问题描述】:

我有两个用 Rickshaw 渲染的图表,非常好。我有一个滑块,我希望能够操纵这两个图表,但它现在所做的是操纵我声明的最后一个图表:

//graph one
var graph_one = new Rickshaw.Graph( {
        element: document.querySelector("#chart_one"),
        height: 150,
        width: 170,
        renderer: 'bar',
        series: data
} );

//slider code
var slider_one = new Rickshaw.Graph.RangeSlider({
    element: document.querySelector('#slider-range'),
    graph: graph_one
});

graph_one.render();

//graph two
var graph_two = new Rickshaw.Graph( {
        element: document.querySelector("#chart_two"),
        renderer: 'line',
        height: 150,
        width: 170,
        series: data
} );

//slider code
var slider_two = new Rickshaw.Graph.RangeSlider({
    element: document.querySelector('#slider-range'),
    graph: graph_two
});

graph_two.render();

是否可以让一个滑块操纵两个图表?

【问题讨论】:

  • 我将尝试编辑rickshaw.js。

标签: javascript slider d3.js rickshaw


【解决方案1】:

我通过编辑 rickshaw.js 来实现这一点,特别是编辑 Rickshaw.Graph.RangeSlider 以接受图形数组作为图形变量:

Rickshaw.Graph.RangeSlider = function(args) {

    var element = this.element = args.element;
    var graph = this.graph = args.graph;
    //added by bozdoz
    if(graph.constructor === Array){
            $( function() {
                $(element).slider( {
                    range: true,
                    min: graph[0].dataDomain()[0],
                    max: graph[0].dataDomain()[1],
                    values: [ 
                        graph[0].dataDomain()[0],
                        graph[0].dataDomain()[1]
                    ],
                    slide: function( event, ui ) {
                        //on slide, move both graphs
                        for(var i=0; i < graph.length; i++){
                            graph[i].window.xMin = ui.values[0];
                            graph[i].window.xMax = ui.values[1];
                            graph[i].update();

                            // if we're at an extreme, stick there
                            if (graph[i].dataDomain()[0] == ui.values[0]) {
                                graph[i].window.xMin = undefined;
                            }
                            if (graph[i].dataDomain()[1] == ui.values[1]) {
                                graph[i].window.xMax = undefined;
                            }
                        }
                    }
                } );
            } );
            graph[0].onUpdate( function() {

                var values = $(element).slider('option', 'values');

                $(element).slider('option', 'min', graph[0].dataDomain()[0]);
                $(element).slider('option', 'max', graph[0].dataDomain()[1]);

                if (graph[0].window.xMin == undefined) {
                    values[0] = graph[0].dataDomain()[0];
                }
                if (graph[0].window.xMax == undefined) {
                    values[1] = graph[0].dataDomain()[1];
                }

                $(element).slider('option', 'values', values);

            } );
            ...

然后,在声明图表时,我只需要将滑块代码添加到最后一个图表中,包括两个图表变量作为数组:

var slider_two = new Rickshaw.Graph.RangeSlider({
    element: document.querySelector('#slider-range'),
    graph: [graph_one, graph_two]
});

完全按照我想要的方式工作:http://jsfiddle.net/bozdoz/k4NmL/

【讨论】:

  • 我们最好不要编辑 rickshaw.js,而是创建一个新版本的 Rickshaw.Graph.RangeSlider(比如... Rickshaw.Graph.SlideRangeMulti)来扩展原始版本。这将使 Rickshaw 未来的升级变得更加容易,因为您不必每次都重新应用补丁。
【解决方案2】:

这是最新版本的 Rickshaw 的上述代码的修改版本:

Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({

initialize: function(args) {

    var element = this.element = args.element;
    var graph = this.graph = args.graph;
    this.onslide = args.onslide;

    this.build();

    if( graph.constructor === Array ) {
        for( var i=0; i<graph.length; i++ ) {
            graph[i].onUpdate( function() { this.update() }.bind(this) );
        }
    } else {
        graph.onUpdate( function() { this.update() }.bind(this) );
    }
},

build: function() {

    var element = this.element;
    var graph = this.graph;
    var onslide = this.onslide;

    if( graph.constructor === Array ) {
        $( function() {
            $(element).slider( {
                range: true,
                min: graph[0].dataDomain()[0],
                max: graph[0].dataDomain()[1],
                values: [
                    graph[0].dataDomain()[0],
                    graph[0].dataDomain()[1]
                ],
                slide: function( event, ui ) {
                    for( var i=0; i<graph.length; i++) {
                        graph[i].window.xMin = ui.values[0];
                        graph[i].window.xMax = ui.values[1];
                        graph[i].update();

                        // if we're at an extreme, stick there
                        if (graph[i].dataDomain()[0] == ui.values[0]) {
                            graph[i].window.xMin = undefined;
                        }
                        if (graph[i].dataDomain()[1] == ui.values[1]) {
                            graph[i].window.xMax = undefined;
                        }
                    }
                    if( onslide ) {
                        onslide(ui.values[0],ui.values[1]);
                    }
                }
            } );
        } );

        element[0].style.width = graph[0].width + 'px';

    } else {
        $( function() {
            $(element).slider( {
                range: true,
                min: graph.dataDomain()[0],
                max: graph.dataDomain()[1],
                values: [
                    graph.dataDomain()[0],
                    graph.dataDomain()[1]
                ],
                slide: function( event, ui ) {

                    graph.window.xMin = ui.values[0];
                    graph.window.xMax = ui.values[1];
                    graph.update();

                    // if we're at an extreme, stick there
                    if (graph.dataDomain()[0] == ui.values[0]) {
                        graph.window.xMin = undefined;
                    }
                    if (graph.dataDomain()[1] == ui.values[1]) {
                        graph.window.xMax = undefined;
                    }
                    if( onslide ) {
                        onslide(ui.values[0],ui.values[1]);
                    }
                }
            } );
        } );

        element[0].style.width = graph.width + 'px';
    }
},

update: function() {

    var element = this.element;
    var graph = this.graph;

    var values = $(element).slider('option', 'values');

    if( graph.constructor === Array ) {
        graph = graph[0];
    }

    $(element).slider('option', 'min', graph.dataDomain()[0]);
    $(element).slider('option', 'max', graph.dataDomain()[1]);

    if (graph.window.xMin == null) {
        values[0] = graph.dataDomain()[0];
    }
    if (graph.window.xMax == null) {
        values[1] = graph.dataDomain()[1];
    }

    $(element).slider('option', 'values', values);
}
});

【讨论】:

    【解决方案3】:

    已经实现的更好的解决方案是使用 Rickshaw.Graph.RangeSlider.Preview 类。

    可以使用graphgraphs参数来管理1个单图或图数组。

    例如。

    var slider = new Rickshaw.Graph.RangeSlider.Preview ({
    	graphs: [graphone, graphtwo],
    	element: document.querySelector('#slider')
    });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多