How to add graphics / data to Rickshaw using d3.js?

Here is what I have:

http://jsfiddle.net/bozdoz/Q6A3L/

rickshaw d3.js graph

Code for background bars:

maxData = 80000000; maxHeight = 250; var yScale = d3.scale.linear(). domain([0, maxData]). // your data minimum and maximum range([0, maxHeight]); // the pixels to map to, eg, the height of the diagram. var riskpoints = [62000000,48000000,30000000]; var rectDemo = d3.select("#chart"). append("svg:svg"). attr("width", 400). attr("height", maxHeight). attr('class','risk'); rectDemo.append("svg:rect"). attr("x",0). attr("y", maxHeight - yScale(riskpoints[0])). attr("height", yScale(riskpoints[0]) - yScale(riskpoints[1])). attr("width", '100%'). attr("fill", "rgba(0,100,0,.3)"); rectDemo.append("svg:rect"). attr("x",0). attr("y", maxHeight - yScale(riskpoints[1])). attr("height", yScale(riskpoints[1]) - yScale(riskpoints[2])). attr("width", '100%'). attr("fill", "rgba(100,100,0,.3)"); rectDemo.append("svg:rect"). attr("x",0). attr("y", maxHeight - yScale(riskpoints[2])). attr("height", yScale(riskpoints[2])). attr("width", '100%'). attr("fill", "rgba(100,0,0,.3)"); 

This is exactly what I want, except that I made the red, yellow, green background stripes a fixed height.

When you use the slider or, more importantly, when the graph will be regenerated (what will happen to the actual data), I want the background bars to adjust to the correct height.

For example, in the image, the green bar is somewhere between 300M and 200M. If you delete all the chart data, except for the red (vertical) bars, the green bar (horizontal) will be slightly higher than 40 M. This is because the position / height of the background bars is not restored, while the position / height of the graph data is regenerated with javascript rickshaw.

How can I put this data into a rickshaw chart so that it is regenerated?

+4
source share
2 answers

The solution is to configure the update function to calculate the new heights of the background bars, to display the displayed bars you can use graph.series.active (); you may also like to keep the wars in the same volume ....

therefore the solution itself:

 var maxHeight; var background_update = function(graph) {   //skip 1st time;   if (maxHeight === undefined) {return;}   var series=graph.series.active();   maxHeight=yScale(get_maximum_all(series));  //console.log(maxHeight);   var red_riskpoint=get_maximum("y",series[0]);   var yellow_riskpoint=get_maximum("y",series[1]);   var green_riskpoint=get_maximum("y",series[2]);  //console.log(graph.series.active());   console.log(yScale(red_riskpoint),yScale(yellow_riskpoint),yScale(green_riskpoint));    // return;     b_red.attr("y", maxHeight - yScale(red_riskpoint)).attr("height", yScale(red_riskpoint));   b_yellow.attr("y", maxHeight - yScale(yellow_riskpoint)).attr("height", Math.abs(yScale(yellow_riskpoint) - yScale(red_riskpoint)));   b_green.attr("y", maxHeight - yScale(green_riskpoint)).attr("height", Math.abs(yScale(green_riskpoint) - yScale(yellow_riskpoint)));   console.log(maxHeight-yScale(green_riskpoint)); }; var get_maximum_all=function(series) {   var max=0;   for (var i in series) {     var stack=series[i].stack;     for (n in stack) {       if (stack[n].y>max) {max=stack[n].y;}       if (stack[n].y0>max) {max=stack[n].y0;}     }   }   return max; }   var get_maximum=function(tag,object){   var max=0;   for (var i in object.stack) {     if (object.stack[i][tag]>max) {max=object.stack[i][tag];}   } return max;   } Rickshaw.Graph.RangeSlider = function(args) {   var element = this.element = args.element;   var graph = this.graph = args.graph;   $(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;       }     }   });   element.style.width = graph.width + 'px';   graph.onUpdate(function() {     var values = $(element).slider('option', 'values');     $(element).slider('option', 'min', graph.dataDomain()[0]);     $(element).slider('option', 'max', graph.dataDomain()[1]);     if (graph.window.xMin == undefined) {       values[0] = graph.dataDomain()[0];     }     if (graph.window.xMax == undefined) {       values[1] = graph.dataDomain()[1];     }     $(element).slider('option', 'values', values);     background_update(graph);   }); } 

the other code is almost the same as you put in the script,

my violin is here

Please note that I am not sure how to calculate the risks, I just tried to get the maximum. I'm sure you can do the calculations in terms of probability when viewing console.log(series)

b_red, b_green, b_yellow - this is d3 selection of initialized background bars.

+3
source

I found several solutions using @eicto's answer.

 var maxHeight = 250; var theSVG = d3.select("#chart svg"); //from @eicto: get the maximum value on the current chart function get_maximum_all(series) { var max=0; for (var i in series) { var stack=series[i].stack; for (n in stack) { if (stack[n].y>max) {max=stack[n].y;} if (stack[n].y0>max) {max=stack[n].y0;} } } return parseInt(max); } //create a function to call on graph update event function createRiskPoints(riskpoints){ //these variables need to change on each graph update var series = graph.series.active(); //this variable should be get_max_y_axis, but I don't know how to do that var maxData = get_maximum_all(series); var yScale = d3.scale.linear(). domain([0, maxData]). range([0, maxHeight]); //using dummy values for now var riskpoints = (riskpoints) ? riskpoints : [300000000,200000000,100000000]; //insert the bars so they go behind the data values theSVG.insert("svg:rect", ":first-child"). attr("x",0). attr("y", maxHeight - yScale(riskpoints[0])). attr("height", yScale(riskpoints[0]) - yScale(riskpoints[1])). attr("width", '100%'). attr("fill", "rgba(0,100,0,.2)"); theSVG.insert("svg:rect", ":first-child"). attr("x",0). attr("y", maxHeight - yScale(riskpoints[1])). attr("height", yScale(riskpoints[1]) - yScale(riskpoints[2])). attr("width", '100%'). attr("fill", "rgba(100,100,0,.2)"); theSVG.insert("svg:rect", ":first-child"). attr("x",0). attr("y", maxHeight - yScale(riskpoints[2])). attr("height", yScale(riskpoints[2])). attr("width", '100%'). attr("fill", "rgba(100,0,0,.2)"); } //call the function createRiskPoints(); //call the function on graph update: thanks to @eicto graph.onUpdate( createRiskPoints );​ 

Now the stripes change when you change the schedule; however, they do not scale. This will be my next task.

http://jsfiddle.net/bozdoz/Q6A3L/

+1
source

Source: https://habr.com/ru/post/1445631/


All Articles