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?
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?
Share Improve this question asked Nov 16, 2012 at 0:14 bozdozbozdoz 12.9k8 gold badges73 silver badges100 bronze badges 1- I'm going to try to edit the rickshaw.js. – bozdoz Commented Nov 16, 2012 at 16:19
3 Answers
Reset to default 4I acplished 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/bozdoz/k4NmL/
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')
});