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.
Related
I need to to represent a Parallel Coordinates with d3.js. First of all I have no idea if what I think is possible to achieve (and if the Parallel Coordinates is the right chart).
I will explain my idea: I take data from a database and I expose them in a JSON and I store them in an array of objects (with JavaScript).
This is an example of the data http://pastebin.com/DZcMqDMc.
I would like to represent along the abscissa axis years (though there are years repeating themself, as you can see from data example), while along the ordinate axis values of those years (values are in percent, ranging from 1 to 100).
I would like to represent two lines according to "value1" and "value2" property in the JSON file.
Is it possible? Is Parallel Coordinates the right chart?
The main problem I have right now is that I do not understand how to set right the two domains (abscissa and ordinate).
I am basing on the example Parellel Coordinates of Bostock.
For abscissa I am thinking something like that:
x.domain(
d3.extent(test,
function(d) {
return d.years;
}
)
);
It makes sense or?
Try a multi line chart.That might suit your need.
I am not sure what you are trying.
Simply do a line chart, and produce the vertical lines by formatting the ticks to go from 0 to height ( in your var xAxis code include .tickSize(0-height)). You will have to pick the right number of ticks, as in ticks(), so you just get the lines where you want them.
Check out Parcoords, a d3-based parallel coordinates library. For compatibility with d3 v5 see https://github.com/BigFatDog/parcoords-es which is based on the original Parcoords library (https://github.com/syntagmatic/parallel-coordinates) which relies on an outdated version of d3.
For examples and sample code, check out the following link: http://syntagmatic.github.io/parallel-coordinates/.
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.
First off, thanks in advance for looking at my question!
So if you click on this gist http://bl.ocks.org/markarios/e95914454a1ef4f7f391 I have a bar chart that shows counts vs ppi for different types of devices (tables, cell phones, computer monitors). But I also have screen brightness data. I would like to plot ppi on the x-axis and brightness (nits) on the y-axis.
My current code is this for the bar chart.
dc.barChart("#bar-chart-III")
.width(500) ```
.height(600)
.dimension(ppi)
.group(count_by_ppi )
.x(d3.scale.linear().domain([ppiExtent[0]-1,ppiExtent[1]+1]));
d3.select("#bar-chart-III").append("text").text("PPI");
But where I'm stuck is I have no idea how to define the brightness variable so it can replaces the count_by_ppi variable in the preceding code? Up to this point, I have brightness defined like this.
var brightness = data.dimension(function(d){return d.brightness_nits})
var count_by_brightness = brightness.group().reduceCount();
I tried the following but it doesn't work.
dc.barChart("#bar-chart-III")
.width(500) ```
.height(600)
.dimension(ppi)
.group(brightness)
.x(d3.scale.linear().domain([ppiExtent[0]-1,ppiExtent[1]+1]));
You'll need to create several groups with the same keys as your dimension (ppi) - one group for each brightness bucket you want. Then you'll want to use the dc.js .stack() method to add those groups on to your stacked bar chart (use .group() once and .stack() several times, IIRC).
The stack() method is documented under the stack mixin:
https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#stack-mixin
It seems like this sort of 'group of buckets' is something that is needed fairly often, so I'm going to try to create a helper for it in the Reductio project, but I haven't gotten around to it yet.
I'm using Highcharts for a project in which I have to display two series with about a thousand points each. The x-axis represents a date, and the y-axis a quantity. In addition, each point has an associated list of namesMy data is day-by-day without gaps, with a structure such as
var mydata = [ ...
{x: theDate, y: theValue, names: theNames},
... ]
where theNames is an array of strings. I can access these in the tooltip formatter through this.points.point.names, given that the range displayed on the chart is small enough. If I change the x-axes so that the start date and end date are more than roughly a year apart, then the tooltip is not rendered at all.
One of the possible avenues that I have tried but failed with so far is setting the turboThreshold limit to the length of the longest series plus 1. Setting this lets me at least display a graph when mydata.length > 1000 (the default value). However, this only displays the tooltip if the x-axis range is less than 261. Otherwise, the tooltip disappears entirely, as does the point.data object where I'm getting the name from.
I'm also not great at JavaScript, but I was wondering if there were a way to separate the names of the points from the array containing them (in my examples, myData1 and myData2) and somehow access those names from the tooltip function without going through the current point.
Here is the link to the jsFiddle demonstrating this issue.
All help is appreciated!
The problem is in dataGrouping, when disabled works fine: http://jsfiddle.net/34tfg/1/
DataGrouping is method in Highcharts to approximate points and display them when width of the chart is not enough, e.g. how to display 10 000points in a chart of width 1 000px -> 10 points in a one pixel..? And when dataGrouping is used, new points are created, so all your custom options like 'names' etc. are lost (at least not accessible).
Code:
plotOptions: {
line: {
dataGrouping: {
enabled: false
},
turboThreshold: 10000
}
},
I have a scatter series with two points that have the same coordinates. Each point has different data associated with it (for example weight and height of different people - two different people can have exactly the same height and weight):
series: [ {
data: [{x:193.5, y:80.7, name:'danny'},
{x:193.7, y:90.7, name:'oren'},
{x:193.7, y:90.7, name:'josef'},
{x:195.5, y:80.3, name:'thomas'}]
}]
Full example at jsfiddle.
When viewing the tooltips of the chart, the tooltip of the second point shows:
Oren: 193.7,90.7
Making the data of josef inaccessible.
I would like to make the data of both josef and oren accessible, for example by putting them inside of the same tooltip.
Oren: 193.7,90.7
Josef: 193.7,90.7
How would you achieve this effect?
assume a very large data set - iteration over the entire series each time is not an option.
You could use the Tooltip formatter ( http://api.highcharts.com/highcharts#tooltip ) to manually format your tooltips.
In the formatter compare x and y value of all other points in the series(this.series) If the values are the same, add the name of these points to the tooltip.