Is it possible to build a stacked bar chart in D3 with different stacked levels?
I've been reading about it but cud only find examples which has same stacked levels.
In other words,
Instead of this JSON -
var layers = [
{
"name": "apples",
"values": [
{ "x": 0, "y": 11},
{ "x": 1, "y": 10},
{ "x": 2, "y": 10}
]
},
{
"name": "oranges",
"values": [
{ "x": 0, "y": 9},
{ "x": 1, "y": 9},
{ "x": 2, "y": 9}
]
}
];
Can we create a bar chart with -
var layers = [
{
"name": "apples",
"values": [
{ "x": 0, "y": 11},
{ "x": 1, "y": 10},
{ "x": 2, "y": 10}
]
},
{
"name": "oranges",
"values": [
{ "x": 0, "y": 9}
]
}
];
I read -
https://bl.ocks.org/mbostock/3886208
https://bl.ocks.org/mbostock/1134768
https://github.com/mbostock/d3/wiki/Stack-Layout
This is fairly easy to do, depending on how you design your loading of data into the chart.
Essentially the process would be:
Use the data() function with the layers variable, which allows you to then work with each data set individually
Add a g element using the enter() function of the result of step 1
Call data() again, this time using the values of the attached data (.data(function(d){return d.values;}))
Use the enter() function of the result of step 3 to generate the bars
Note that to get things to actually stack you will need to keep track of the current stacked height of each x position. All you have to do is generate an array of zeroes and update the value at index d.x when setting the rectangle's y attribute.
Fiddle showing a quick sample. To make this a fully working example, you'll have to add axes/scales and all the extra things.
Related
I would like to create a jsonpath to take first part of whole json. I have trouble because I dont have any key for sub jsons.
For Example, I have this json;
[
[
"name",
"surname",
"age"
],
[
{
"X": "Mike",
"Y": "Tyson"
},
{
"X": "Irina",
"Y": "Shat"
}
]
]
I want to divide this json to 2 different json;
[
"name",
"surname",
"age"
]
[
{
"X": "Mike",
"Y": "Tyson"
},
{
"X": "Irina",
"Y": "Shat"
}
]
I try to use index but doesn't work.
I am currently in the process of creating a bubble chart using AmCharts. For the most part the process is quite easy.
I however the bubbles AmCharts create seem to be very weirdly scaled in proportion to each other. If I e.g. have two bullets with value "9" and "3", no matter what I do the graph will set the bullet with value "9" to be as large as allowed by maxBulletSize (this can be wider than a column which is also just weird) and the other as small as possible.
What I would like is to have the values fall in the range from 1 to 10, where 10 should fill out approx. a column (it should however never be bigger than a column as it can then overlap with other bubbles). Thus even though I may not actually have a bullet of size "1", size "3" should remain the same.
Is this possible?
Normally, this is not possible using just configuration options. However, you can apply this simple workaround: just add two invisible bullets: one with value 1 and the other 10. It will ensure that the scale will always be the same for any in-between values.
var chart = AmCharts.makeChart( "chartdiv", {
"type": "xy",
"dataProvider": [ {
"y": 10,
"x": 14,
"value": 3
}, {
"y": 5,
"x": 3,
"value": 6
}, {
"y": 10,
"x": 8,
"value": 4
}, {
"y": 0,
"x": 0,
"value": 1,
"alpha": 0
}, {
"y": 0,
"x": 0,
"value": 10,
"alpha": 0
} ],
"graphs": [ {
"balloonText": "[[value]]",
"balloonFunction": function(item) {
// using this in order not to display balloons for
// hidden bullets
if (item.alpha === 0)
return "";
return "" + item.dataContext.value;
},
"bullet": "circle",
"lineAlpha": 0,
"valueField": "value",
"xField": "x",
"yField": "y",
"alphaField": "alpha",
"minBulletSize": 10,
"maxBulletSize": 100
} ]
} );
#chartdiv {
width: 100%;
height: 300px;
}
<script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="http://www.amcharts.com/lib/3/xy.js"></script>
<div id="chartdiv"></div>
I have a 2D array of x and y coordinates in Javascript, where the array looks like this:
---> 0: 0 1 .....
{x:1, y:1}, {x:1, y:2} .....
---> 1: 0 1 .....
{x:1, y:1}, {x:1, y:2} .....
So if I for instance write Array[0][0].x, the output is 1.
I would like to turn this array into a JSON string, which would have the following syntax:
{
"name0": [
{
"0": [
{
"x": "1",
"y": "1"
},
{
"x": "1",
"y": "2"
}
],
"1": [
{
"x": "1",
"y": "2"
},
{
"x": "2",
"y": "1"
}
]
}
],
"name1": [
{
"0": [
{
"x": "1",
"y": "1"
},
{
"x": "1",
"y": "2"
}
],
"1": [
{
"x": "1",
"y": "2"
},
{
"x": "2",
"y": "1"
}
]
}
]
}
where name0 and name1 (nameX) are not inside the mentioned 2d array, but passed from somewhere else inside the function where I am creating the JSON. Also, each nameX object is supposed to be pushed into the JSON with the call of this function.
var data;
data[name1] = yourDataA;
data[name2] = yourDataB;
json = JSON.parse(data);
Just prepare your data var the way you need it.
use https://github.com/douglascrockford/JSON-js library, just include the code and use the JSON.stringify() method for converting your array.
https://github.com/mbostock/d3/wiki/Stack-Layout
http://mbostock.github.com/d3/ex/stream.html
I'm trying to make a streamgraph with D3.js. Looking at the example, we see that the data is formulated through the helper function stream_layers(n, m). In this example an array is returned as described in the API. The API describes input x, y and y0. But the example uses x, y0, y1.
My dataset is formulated similarly to the one described in the API:
{
"name": "apples",
"values": [
{ "year": -2000, "y": 91},
{ "year": -1950, "y": 290}
]
},
{
"name": "oranges",
"values": [
{ "year": -2000, "y": 9},
{ "year": -1950, "y": 49}
]
}
What would a helper function that stacks this dataset look like? The example returns a 3D array (one dimension for the number of layers, one for the number of samples m and one for the y-values at each sample).
I am a d3 newbie and I've been trying to customize the Streamgraph example (http://mbostock.github.com/d3/ex/stream.html):
I have run into some issues:
I want to assign a custom data property (for examples sake, lets just say its a label called "type") to each layer in the stream so that when you hover over that layer, a popup box appears with the "type" listed for that layer.
When I input my data source into the graph I use this code:
vis.selectAll("path")
.data(data0)
.enter().append("path")
The graph only seems to take data of the format:
[
[
{
"x": 0,
"y": 91,
"y0": 1.11
},
{
"x": 1,
"y": 290,
"y0": 1.11
}
],
[
{
"x": 0,
"y": 9,
"y0": 1.11
},
{
"x": 1,
"y": 49,
"y0": 1.11
}
]
]
Where each sub-array above corresponds to a layer in the streamgraph.
How can I pass data to the graph that allows me to add an extra "type" property for each layer?
Basically so that when I refer to the datum of a layer, I can just type something like d.type and extract that property?
I originally came up with a really hackish way to do it:
[
{
"x": 0,
"y": 9,
"y0": 1.11,
"type": "listings"
},
{
"x": 1,
"y": 49,
"y0": 1.11,
}
]
and then I refer to it in the layer datum by saying d[0].type, but this doesn't seem like the proper way to do it.
Use stack.values, and then wrap each layer's data points with some additional data for the layer. Your data will look something like this:
[
{
"type": "apples",
"values": [
{ "x": 0, "y": 91},
{ "x": 1, "y": 290}
]
},
{
"type": "oranges",
"values": [
{ "x": 0, "y": 9},
{ "x": 1, "y": 49}
]
}
]
And the stack layout like this:
var stack = d3.layout.stack()
.offset("wiggle")
.values(function(d) { return d.values; });