Domanda

I have two graphs rendering with Rickshaw, perfectly fine. I have a single slider that I want to be able to manipulate both graphs, but what it's doing now is manipulating the last graph that I declare:

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

Is it possible to have one slider manipulate two graphs?

È stato utile?

Soluzione

I accomplished this by editing the rickshaw.js, specifically editing Rickshaw.Graph.RangeSlider to accept arrays of graphs as a graph variable:

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

            } );
            ...

Then, when declaring the graphs, I only need to add the slider code to the last graph, including both graph variables as an array:

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

Works exactly how I wanted it to work: http://jsfiddle.net/bozdoz/k4NmL/

Altri suggerimenti

Here is a modified version of the above code for the most recent version of 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);
}
});

A better solution already implemented is to use the Rickshaw.Graph.RangeSlider.Preview class.

It can take the parameters graph or graphs in order to manage 1 single graph or a graph array.

Eg.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top