d3 vertical bar chart - javascript

How can I draw chart like this?
I have data (for example):
{
"USA": {
"value": 10,
"companies": [ "Apple", "Google" ],
"color": "red"
},
"Germany": {
"value": 3,
"companies": [ "SAP" ],
"color": "green"
}
}
"value" is for the left side.
"companies" is for the right side.
"value" != "compnaies" length.
I can't figure out what kind of graph I must use.
I'll try hierarchy, but it must have only one root.

i made a small poc but i'm not sure what you want so i can't really got much further please take a look at this : https://jsfiddle.net/z9bcfdvk/
i used the dataser you provided and added one entry:
Let me know if you want more detail.
var data = [
{
country: "USA",
"value": 10,
companies: ["Apple", "Google"],
"color": "#123445"
},
{
country: "Germany",
"value":
3,
companies:
["SAP"],
"color":
"#987456"
}, {
country: "France",
"value":
1,
companies:
["RENAULT"],
"color":
"#8b9838"
}
]

Related

Accessing nested array properties

This may be extremely simple but I've not been able to figure out how to iterate over and access the properties in the following mix (I think) of arrays and nested objects:
myFilters = {
"color_Filter": [{
"name": "BLUE",
"count": 1,
"dataId": "BLUE"
},
{
"name": "Black",
"count": 5,
"dataId": "Black"
},
{
"name": "Blue",
"count": 14,
"dataId": "Blue"
}
],
"size_Filter": [{
"name": "10",
"count": 16,
"dataId": "10"
},
{
"name": "12",
"count": 16,
"dataId": "12"
}
]
}
What would the correct looping structure be here to pull out name, count etc from the above? The desired output is to output a string from the above with color_Filter=BLUE,Black,Blue/size_Filter=10,12
I've tried a few different approaches and none of them have been successful so far.
You could map the entries of the object and create a string for each key. Get the name from the value array using map. Then join the array of strings with a /
const myFilters = {color_Filter:[{name:"BLUE",count:1,dataId:"BLUE"},{name:"Black",count:5,dataId:"Black"},{name:"Blue",count:14,dataId:"Blue"}],size_Filter:[{name:"10",count:16,dataId:"10"},{name:"12",count:16,dataId:"12"}]};
const output = Object.entries(myFilters)
.map(([k,arr]) => `${k}=${arr.map(a => a.name)}`)
.join("/")
console.log(output)

How to handle different series of data in d3.js

I am using nvd3's multibar chart. The problem is the series I provide to the chart is not symmetrical. Like there will be values for a some series and others won't have.
[
{
"key": "ALL POS",
"color": "#39a5cf",
"values": [
{
"x": "4/01/2012",
"y": 54,
"series": 0
}
]
},
{
"key": "MIX POS",
"color": "#2227f4",
"values": [
{
"x": "4/01/2012",
"y": 34,
"series": 1
}
]
},
{
"key": "PURE POS",
"color": "#9fa9f7",
"values": []
}
]
You can see the pure pos series doesnt have values compared to the other two. Because of this the stacked effect is not working. Can someone help me regarding this?

Loading JSON with D3 when columns are defined separately

I'm using d3.js and I'm having hard time understanding how can I load a JSON which represents a table (columns and rows), which the columns are defined separately.
A normal JSON, which I have no problem loading may look like this:
[
{
"id": 1,
"name": "A green door",
"price": 12.50
},
{
"id": 2,
"name": "A red door",
"price": 12.50
},
{
"id": 3,
"name": "A blue door",
"price": 12.50
}
]
The corresponding JSON with separated columns will look like this:
{
"columns": [
{
"ColumnName":"id",
"DataType":"number"
},
{
"ColumnName":"name",
"DataType":"string"
},
{
"ColumnName":"price",
"DataType":"number"
}
],
"rows": [
[
"1",
"A green door",
"12.50"
],
[
"2",
"A red door",
"12.50"
],
[
"3",
"A blue door",
"12.50"
]
]
}
Is it possible to make d3.js load this kind of JSON without reconstructing a new JSON?
The original structure of the JSON that I receive is not changeable.
Thank you for helping.
There won't be any problem in loading the JSON with separated columns(Format 2) with d3. You will just need to convert the JSON format after loading it, to match the required format of your d3 layout. For that, you may try the code as shown below.
d3.json("path/to/column_json_file_name.json", function(error, data) {
if (error) return console.warn(error);
var columns = data.columns.map(function(d){ return d.ColumnName });
var jsonInRquiredFormat = data.rows.map(function(row,i){
var ob = {};
ob[columns[0]] = parseInt(row[0]);
ob[columns[1]] = row[1];
ob[columns[2]] = parseFloat(row[2]);
return ob;
});
console.log(jsonInRquiredFormat);
});
Output obtained for sample input:
[{
"id": 1,
"name": "A green door",
"price": 12.5
}, {
"id": 2,
"name": "A red door",
"price": 12.5
}, {
"id": 3,
"name": "A blue door",
"price": 12.5
}]

Format data to be used in Highcharts series

Hi I am trying to make a stacked bar chart using Highcharts, but the way the data has to be formatted to be consumed as a a series is tripping me up.
series: [{
name: 'John',
data: [5]
}, {
name: 'ee',
data: [2]
}, {
name: 'aa',
data: [7]
},{
name: 'zz',
data: [4]
},{
name: 'Joe',
data: [3]
}]
That is how one of the examples is on their site for a stacked bar chart. I am using $http.get() to originally get data from a webservice, in JSON format like so :
{
"id": 13,
"name": "JohnSnow",
"totalScore": 5.239947894580996,
"models": [
{
"id": 0,
"name": "Grey",
"score": 75.5
},
{
"id": 1,
"name": "Black",
"score": 1.2355425046127677
},
{
"id": 2,
"name": "Purple",
"score": 24.0705126173457
},
{
"id": 3,
"name": "Teal",
"score": 28.981312850901684
},
{
"id": 4,
"name": "Yellow",
"score": 31.373482114014525
},
{
"id": 5,
"name": "Green",
"score": 22.02040979235661
},
{
"id": 6,
"name": "Red",
"score": 11.137161646416322
},
{
"id": 7,
"name": "Blue",
"score": 25.83014182677578
},
{
"id": 8,
"name": "Orange",
"score": 4.793888180490194
}
]
}
My original approach was to go through the returned data from the $http.get() call and add a JSON object to an array that I would then set series equal to but that isn't working out too well. What are some other options, or are there easier ways to get it in the format. The data has to stay in that format on the webservice, so changing is out of the question. I have a plunker I am trying to get working here.
interesting question, I normally use either angular.forEach or a library called underscore to handle data processing in angularJS. Here is the forEach version.
data = $http.get(); // suppose you have the data
result = [];
angular.forEach(data.models, function(item) {
// simple way is to take item as the original form
result.push(item);
// or do your own way
result.push({
name: item.name,
data: [item.score]
});
});
Now the result variable is the one you want now.

Fill gaps in NVD3.js

I am trying to make horizontal grouped stacked bar graph in NVD3.js.
Everything works great until I got a "gap" in my JSON data like bellow:
[{
"key": "Education & news",
"values": [{
"label": "2014-02-26",
"value": 702
}, {
"label": "2014-02-27",
"value": 204
}, {
"label": "2014-02-28",
"value": 3213
}]
}, {
"key": "Entertainment",
"values": [{
"label": "2014-02-26",
"value": 21
},
//Missing entry for 2014-02-27
{
"label": "2014-02-28",
"value": 3213
}]
}]
The error which I got is Uncaught TypeError: Cannot read property '1' of undefined in d3.js. The example and the error of the problem I put on http://jsfiddle.net/vaa3V/
Can I somehow fill gaps automatically?
#shabeer90's comment is on track. You can use underscore.js to get the domain values and apply a sensible default.
//Find domain values
DEFAULT = 0
defaults = _.chain(data)
.pluck('values')
.flatten().pluck('label')
.uniq()
.value()
.map( function(item){ return {label:item, value:DEFAULT} })
// Group by 'label' so we can apply defaults
defaults = _.groupBy(defaults, 'label'))
// Apply defaults
_.each(data, function (series) {
grouped = _.groupBy(series.values, 'label')
series.values = _.flatten( _.defaults(grouped, defaults))
})
Should give you:
[
{
"key": "Education & news",
"values": [
{
"label": "2014-02-26",
"value": 702
},
{
"label": "2014-02-27",
"value": 204
},
{
"label": "2014-02-28",
"value": 3213
}
]
},
{
"key": "Entertainment",
"values": [
{
"label": "2014-02-26",
"value": 21
},
{
"label": "2014-02-28",
"value": 3213
},
{
"label": "2014-02-27",
"value": 0
}
]
}
]

Categories