I need to draw a rather simple graph for a web project.
The data will always be the same, so the graph line will not change. However, I need to draw on top of the graph 2 projected lines, highlighting some aspect of the graph. These lines will change depending on some variable.
Here is what I am trying to achieve:
I looked at Chart.js, Chartist and a few other libraries but did not see any examples that will draw those projected lines that I need.
Can someone please point me to a library which can accomplish this?
You can achieve it with highcharts.
I have found some almost exactly suiting example and slightly modified it:
http://jsfiddle.net/mt2becws/1/
Below there are calls setting "crosshair" after some time:
setTimeout(function() {
addCrosshair(3,14.5);
}, 1000);
setTimeout(function() {
addCrosshair(2,5.7);
}, 2000);
And the part of the code really doing it is:
function addCrosshair(x,y) {
chart.xAxis[0].addPlotLine({
id: 'xPlotLine'+x,
value: x,
width: 1,
color: '#C0C0C0'
});
chart.yAxis[0].addPlotLine({
id: 'yPlotLine'+y,
value: y,
width: 1,
color: '#C0C0C0'
});
}
Managed to do this using D3, by following this example here My Favorite tooltip method for a line graph
Had to modify a few things, like the positioning of the tooltips (also using divs for this so I can also style them) and stop the projected x line where it meets the graph path, amongst other things.
But here is a snapshot of the result:
Related
I am trying to build a waterfall chart which will have heavily skewed data(max 45000, min 4), to make the smaller values look significant amount and I am trying to break the yaxis to achieve that. However I am unable to find a generic logic as where exactly to break the yaxis so that the graph looks good for any data. Below is my code.
yAxis: {
title: {
text: 'USD'
},
// calculate percentage of first value for breaking
breaks: [{
from: data[0]*0.05, // break starts at 5% of 7311
to: data[0] * 0.97 // and ends at 97% of 7311
}],
events: {
pointBreak: pointBreakColumn
}
},
http://jsfiddle.net/Saibabu276/4cdrqnbj/61/
Also I am getting axis broken on the second bar in below case for the reason I couldn't figure out. Please Help!!
Setting the yAxis.type to logarithimic is the best way to work with skewed data.
Logarithmic axes can be useful when dealing with data with spikes or large value gaps, as they allow variance in the smaller values to remain visible.
More information with type scale use in charts, you can read on the Highcharts blog.
I would like to create a d3-based plot which graphs a plot within a tooltip. Unfortunately, I haven't found any examples on the web. Here is a sample JSON file.
[{"x":[0.4],
"y":[0.2],
"scatter.x":[0.54,0.9297,0.6024,-1.9224,2.2819],
"scatter.y":[0.4139,1.1298,-0.1119,2.3624,-1.1947]},
{"x":[0.1],
"y":[0.9],
"scatter.x":[-0.8566,-0.5806,-0.9326,0.8329,-0.5792],
"scatter.y":[-0.5462,-0.7054,1.0264,-3.4874,-1.0431]}]
The idea is to have a scatter plot for (x,y) coordinates first. However, when one mouses over a point, a different scatter plot within a tooltip appears based on [scatter.x, scatter.y] coordinates for that respective point.
I can do the scatter plots separately but have been struggling to put them together. Could anyone shed some light on this and/or provide a minimal example?
This was too long for a comment but I'm not certain if it's the answer you were looking for. One of the issues you might find is that your nested data is formatted differently-- one uses JSON objects with x and y, while the other uses two arrays of points.
My solution to this would be to create an extensible function:
function makeScatterPlot(elem, width, height, data, fill)
elem, width, height, and data are the core parameters: which element to attach the chart to, the size of the chart, and the data for the chart (in the JSON object format).
This function would generate all necessary items for the chart and add the chart to the provided element.
Then you want to bind to mouseover of your main chart, and in that function you'll have to do a bit of data modification to re-organize the two arrays into the JSON object structure.
function mainMouseover(d){
var newData = [];
for (var i = 0; i < d["scatter.x"].length; i++){
var t = {x: [0], y: [0]};
t.x[0] = d["scatter.x"][i];
t.y[0] = d["scatter.y"][i];
newData.push(t);
}
var newG = mainG.append("g").attr("transform", "translate(200,200)");
makeScatterPlot(newG, 100,100, newData, "red");
}
Of course, you would modify the translate to match wherever you want your tooltip to be.
Putting this all together you get the following (very crude) fiddle. Hover over either of the black dots to see the sub-chart. Obviously this needs quite a bit of work to be a solid example (i.e. remove the sub-chart on mouseout), but hopefully it will set you in the right direction.
If the tooltip chart is significantly different styling-wise compared to your main chart it may not be the best idea to use an extensible function, and you could just create another custom function instead.
I'm wondering if anyone might be able to help with an issue I'm having with NVD3 where the chart occasionally gets drawn erratically. This typically occurs when I leverage the toggle for labels (i.e. where you can show or hide different lines). The result is something that looks like the following image:
Initially the chart looks normal (i.e. a single line). However, after enabling and disable other lines on the chart, the image ends up being drawn in the erratic fashion shown above.
Any help on how to address this would be greatly appreciated. I was not sure what to search for to describe the issue so apologies if the answer was readily available.
In case anyone else runs across this (which is actually unlikely) I tracked down the issue to the following added lines of code to the "mouseover_line" event (commented out below):
function mouseover_line(evt) {
var yaxis = data[evt.seriesIndex].yAxis === 2 ? yAxis2 : yAxis1;
// evt.series.values[evt.pointIndex].x = d3.time.format('%x')(new Date(evt.point.x));
// evt.series.values[evt.pointIndex].y = d3.format(',')(evt.point.y);
evt.value = evt.point.x;
evt.series = {
value: evt.point.y,
color: evt.point.color,
key: evt.series.key
};
tooltip
.duration(0)
.valueFormatter(function(d, i) {
return yaxis.tickFormat()(d, i);
})
.data(evt)
.hidden(false);
}
I had added those lines in to fix the hover over labels for the line graph (my line graphs had a datetime x-axis and comma separated integer y-axis). Upon adding those lines it seems the extra processing time required resulted in the lines drawing eratically whenever you toggle a series on/off.
Not too sure what the mechanism is that causes the issue but those lines were the root cause.
Possible duplicate question to Bar chart in Javascript: stacked bars + grouped bars
I'm trying to create a stacked bar chart that lets you compare 2 values (dark and mid blue) to last week's data points (the secondary light blues 'behind').
Starting with multiBarChart() with .stacked(true) first I tried merging both weeks into a single array of 14 bars, where the x position could help group the bars. I tried to form my combined array of objects where .x properties' values are 0, 0.3, 1, 1.3, 2, 2.3, etc.
Unfortunately unlike lineChart() it doesn't use the x value for positioning.
Another idea is to exploit the group .stacked(false), providing 4 items (instead of 2) with the same x value. These then appear overlaid on top of each other instead of stacked.
Here the spacing looks good, but how do I stack these 2 by 2?
Hey I just developed grouped+stacked bar chart on d3.js. It is not NVD3 but it may help you.
Source
Demo
Let me just say up front that I am SO not an nvd3 expert. I'm barely past the getting-started stage myself.
That said, it looks like you're making this too hard on yourself.
I think you really want to send nvd3 two sets of data, with the x's matching between the two. (E.g., (1,y1a) corresponding to (1,y2a), then (2,y2a) with (2,y2b), etc.)
You can see this more clearly by the following:
Head to their Live Code page
Select the Group/Stacked Bar Chart.
Select the Data (JSON) tab.
Replace the first function with the following, and observe the resulting x values.:
function() {
return stream_layers(2,10,.1).map(function(data, i) {
alert( 'Stream '+i+': '+JSON.stringify(data));
return {
key: 'Stream' + i,
values: data
};
});
}
Best as I understand it, that's the model you're looking for.
Is it possible to change the styling of a Flot chart's components on the fly – either via the console or a script – after the fact that the chart has been rendered? I.e from somewhere outside the Flot chart's internal configs (which initially defined the styling of the chart).
To put my question into a simple use case: I have a page containing a Flot chart which has the wrong color on the bars. Using Web Inspector's JS console, I want to alter the bars (lines?) color from blue to, say, brown. (And I don't have any means to edit the configs in jquery.flot.js.) Now I wish to inject code from the console, that might change the color of the bars.
I only wish to be hinted of a basic code structure as I'm stuck (nope, I'm not a particularly intermediate or advanced user).
Screenshot 1 – the rendered chart, unaffected (arrow indicates what I want to change):
… Flot's API says:
$.plot(placeholder, data, options)
But I don't want to set/change the data (which has already been plotted out), I just want to change its color representation from blue to, say, brown. The only effect of changing something, that I managed to achieve, was this (terribly clueless) piece of code:
$.plot("#chart", { series: {color: "#6C564C"} });
Which turned the chart into (Screenshot 2):
I don't know why the chart disappeared, and we don't necessarily need to troubleshoot that. All I'm looking for is the simple structure for altering a Flot chart's options by means of code injection.
You can change the colour of an already-drawn series by changing the data object and using setData(). This is faster than calling $.plot() again but it won't recalculate the grid and ticks. If your actual data points don't change, this isn't an issue.
var data = [
{
label: "Your series",
data: rawData,
color: "#f00"
}
]
// Initial draw:
var flotObject = $.plot("#chart", data, options);
// ...
// Change the colour:
data[0].color = "yellow"; // Change only the colour of the original data object
flotObject.setData(data);
flotObject.draw();