I'm trying to make a column graph in Highcharts and it's not working out too hot. I'm essentially trying to give the column a background color that the data point can overlay. I want the effect of stacking without actually stacking if that makes sense. Any thoughts on what I can do?
Essentially I want it to look like a progress bar... there should be a distinct coloring between the top of the bar and the top of the graph itself. I've already tried stacking: percentage, but to no avail. Thoughts?
There are three options that come to mind:
1) To achieve the 'effect' of stacking, actually stack it: use a dummy series with a color set to the background color that you want, and set with values to fill the gap from the actual data.
Example:
http://jsfiddle.net/jlbriggs/Zf8C7/5/
[[edit for questions
The order of the series does not matter for this to work, and neither does the legendIndex.
What does matter, if you are using multiple series, is the stack property for each series - http://api.highcharts.com/highcharts#series.stack
Each group will need its own stack, and the dummy series and real series within each group need to be assigned to the same stack.
In addition, you need to have one overall max value.
Updated example:
http://jsfiddle.net/jlbriggs/4d9tm6b8/4/
(keep in mind, there are much smoother methods to process and build your data - this is a quick and dirty example whose purpose is to show how to properly use the stack property to do what you need)
]]
2) plotBands, as mentioned above
3) using the alternateGridColor property and set your data to skip an x axis
value between each point.
Reference:
- http://api.highcharts.com/highcharts#xAxis.alternateGridColor
Related
I need to draw a graph to display engine status.That is i will be having time like 1-2,2-3,3-4 along axis and by using bar graph i need to display whether engine was on or off at these time.
That is from 1-2 if it is off it will how black and 2-4 if it is on it will show blue color and again if the status is changed it should show black from blue.Right now i have customised jquery high charts for displaying one bar,by removing some parameters.
I need to know how i implment this here or is it possible in this graph?
You can do this with a column range chart, with minimal fudging.
The main issue is making sure you set your data points correctly, and to set grouping:false in the plotOptions. The x value needs to be specified for each data as well, or else they will all be given a separate x value
Example:
http://jsfiddle.net/jlbriggs/o9ck2zLn/
This can easily be adapted to a time axis by supplying the timestamps as the y values.
So I'm generating bar chart in D3.js with a csv file a la the basic columns example. What I want to do is show just one bar at a time for each row of data. A JQuery-like slider will iterate over the csv rows and update the chart. For the user, it'll just look like the single bar's height is changing but the x axis should update with the date as well.
Here's an example of the data that I'll be feeding into it:
DATE,INFLOW (CF),OUTFLOW (CF),STORAGE (CF)
20120101,950400,28857600,11084277600
20120102,60912000,28771200,11099959200
20120103,56505600,28857600,11130451200
20120104,55900800,28771200,11158765200
20120105,55987200,28771200,11189692800
20120106,56419200,28771200,11220620400
20120107,55123200,28684800,11246756400
The only thing I actually want to show is DATE and STORAGE (CF). So I'll probably have to do some parsing of the CSV somewhere to get it in the best shape.
I've attempted this and would post some code but all of my attempts are a mess. I can generate a plausible bar chart with all of the rows at once, but when I attempt to show a single one, everything breaks. Here are the challenges that I could use some guidance one:
How to splice or filter my csv with a slider so that only a single row is selected
Best way to generate a bar chart that only has a single bar from a single row in a csv (every time I try to do this I have trouble with axes and accessing the array values correctly)
Best way to update the bar, changing only height but also updating the x axis ticks
Also any examples would be very helpful! Have been googling like mad but am mostly finding sliders that affect range and scale
There are many pieces to this...parsing and slicing the data, setting up the x axis, etc. Here is one segment of the code.
d3.select("#slider")
.on("input", function() {update(+this.value);});
function update(row) {
viewdata = data.slice((row-1), row);
redraw();
}
Here is a complete PLUNK with the solution. NOTE: I have placed comments in several parts of the code, for orientation. I strongly suggest you fork this plunk so that it will not be lost if I inadvertently delete it.
I'm trying to create a data visualization in d3.js that contains two charts: a parallel-axis plot, and horizontal colorbar chart (I just made up that name, but it's basically a series of colored rectangles). Each line in the parallel-axis plot is associated with a set of rectangles in the colorbar chart.
Right now, mousing over a given line highlights that line, and mousing over a given rectangle highlights that set of rectangles. My goal is to also highlight the associated line or set of rectangles on the opposite chart anytime the user mouses over either chart. This seems like it would be pretty straightforward if I generated both charts with the same function. However, it would be much neater (and more reusable) coding style to give each chart its own function and just connect them somehow. I tried having each within-chart mouseover function call a function defined at a higher level that affected both charts, but this didn't seem to have any effect on the chart that wasn't moused-over. Since I still don't feel like I fully understand how d3.js works on an underlying level, I'd really like to have confirmation that this is a viable way to set up my code. My code is long and complicated, and I really just want advice on the structure, so here is the basic outline:
function chart1(){
make chart
function mouseover(d,i){
do stuff
chart1_globalmouseover(d,i);
}
chartElement.on("mouseover", function(d,i){mouseover(d,i)});
}
function chart2(){
make chart
function mouseover(d,i){
do stuff
chart2_globalmouseover(d,i);
}
chartElement.on("mouseover", function(d,i){mouseover(d,i)});
}
function chart1_globalmouseover(d,i){
do stuff in chart 2's mouseover function
}
function chart2_globalmouseover(d,i){
do stuff in chart 1's mouseover function
}
c1 = chart1();
c2 = chart2();
One way to link the two graphs independent of the code used to create them would be to assign IDs or classes to the elements you may want to select. That is, if graph 2 has an element with ID foo, then in a mouse handler for an element of graph 1, you could say d3.select("#foo").style("stroke", "red") for example. Similarly with classes.
This approach allows you to keep the code completely separate. Moreover, if you use classes, you can assign the same class to things you would want to highlight together (e.g. elements representing the same data). Then d3.selectAll(".class") would select and allow you to manipulate all of them. This would work for an arbitrary number of graphs, not just two -- what changes is simply the number of elements that will be selected.
I need to toggle specific points in a series in Highcharts based on a value in the data object. Is this possible at all? I can't see anything in the API that says a point within a series can be toggled.
I know I can remove points specifically, but I would much rather hide them, as the user will want to show/hide rather frequently, and I don't want to rebuild the whole series every time.
You can use Point.update and set the marker radius to 0.
selectedPoint.update({marker: { radius: 0 }});
The way to go is to use the point.remove and series.addpoint calls. I don't think that highcharts has a concept of hidden points.
I've created a 'donut' chart originally from this jsfiddle, using raphael.
I have tweaked this script to suit my needs and currently have this being rendered.
My aim is to animate each slice (at the same time); for example make the blue slice grow to 60%; and the red slice shrink to 40%.
I have been able to redraw the slices by removing the existing one and quickly re-rendering a new one with adjusted values (e.g. 51, 49). But the problem here is that it is instant.
My question is,
(a) Can I animate this without the need to redraw the object (and how)?
(b) If not, how I can animate this effect using a redraw logic?
Yes. There is an example of doing this very thing on the Raphael demos page where you got the pie chart. See the Growing Pie demo.
You should separate the code in which you generate the path into a standalone function so you can use it later to return new paths. In order to use animate(), you'll need to define a function on the customAttributes object; it should return (at least) an object with the path property set to your slice's new path.
Since you have labels, you'll probably want to modify the code such that the pie slices expand/shrink relative to their center, so that you don't have to move the labels, too, since the labels are centered on their slice's "axis."
Update
Here's a JSFiddle with a simple example, pretty much the same as Dmitri's Growing Pie demo, except more like your chart. I export a setValue() method to change slice sizes and call it when the page loads. See his blog post about adding customAttributes, too.
In my last paragraph above, I was off the mark a bit. Your chart wasn't the one with labels; I had them mixed up. Also, it would be harder to keep slices centered, so I didn't do that after all. The animate() function sets each segment to its new starting and ending points on the circle, and Raphael figures out the intermediate points. As you can see, you can pass multiple arguments in an array.
this.customAttributes.slice = function(a0, a1) { /*...*/ }
// ...
chart.push(paper.path().attr({slice:[0, Math.PI/2 ]})
Can't see all the fiddle because I'm on iPod however it sounds like you need to have an animate call inside a function that you will need to write
Use the callback parameter that calls the function it sits inside.
Code your recursively called function so it eventually completes when all the work is done.
Each call to the function will happen at the end of every elapssed time interval you specify...