Use json file instead of csv in d3.js pie chart - d3.js

There is an example of making pie chart using d3.js https://bl.ocks.org/mbostock/3887235
here in this example .csv file is used.
age,population
<5,2704659
5-13,4499890
14-17,2159981
18-24,3853788
25-44,14106543
45-64,8819342
≥65,612463
I want to use json file.
[
{"age": "<5",
"population": 2704659
},
{"age": "5-13",
"population": 4499890
},
{"age": "14-17",
"population": 2159981
},
{"age": "18-24",
"population": 3853788
},
{"age": "25-44",
"population": 14106543
},
{"age": "45-64",
"population": 8819342
},
{"age": ">=65",
"population": 612463
}
]
what code I need to change in the source file?
I have used
d3.json("data.json", function(error, data) {
But it not worked for me.

Look at this pie chart : https://jsfiddle.net/reko91/qkHK6/1942/
Data is like so :
var data = [{"label":"Category A", "value":20},
{"label":"Category B", "value":50},
{"label":"Category C", "value":30}];
Makes the container using the data :
var vis = d3.select('#chart')
.append("svg:svg")
.data([data])
Makes a variable pie :
var pie = d3.layout.pie().value(function(d) {
return d.value;
});
Then uses this variable :
var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice");
Which in turn gets used to create the slices :
arcs.append("svg:path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", function(d) {
// log the result of the arc generator to show how cool it is :)
console.log(arc(d));
return arc(d);
});
There you go, pie chart made via json :)
This is just an example, obviously can't implement the exact changes unless you show us your code

Related

d3- Color gradient fill based on Temperature

I am looking to create a color gradient along the x axis of a d3 chart as the fill-area under the chart, and I'm not sure where to start. Hoping you can help:)
So for example, I draw a line graph based on dates and values.(x and y). Then underneath the line, I want the color of the fill to reflect the temperature for that day (higher temperatures, warmer colors, etc).
data = [
{"date": "2018-04-10"
"value": "122"
"temperature" "13"
},
{"date": "2018-04-11"
"value": "129"
"temperature" "15"
},
{"date": "2018-04-12"
"value": "114"
"temperature" "17"
},
{"date": "2018-04-13"
"value": "120"
"temperature" "14"
},
{"date": "2018-04-14"
"value": "139"
"temperature" "11"
},
{"date": "2018-04-15"
"value": "120"
"temperature" "10"
},
{"date": "2018-04-16"
"value": "119"
"temperature" "13"
}
]
and say my colors are
colors = ["red","orange","yellow","green","blue","purple" ]
I'm thinking I'd set the area and fill it with a function that will create the color vertically based on the temperature?
var area = d3.svg.area()
.x(function(d, i) { return x(format.parse(d.date)); })
.y0(height)
.y1(function(d) { return y(d.value); });
graph.append("path")
.datum(data)
.attr("class", "area")
.attr('fill', areaFill)
.attr("d", area);
I got this code from THIS codepen to get me started... it's obviously not right but helps show how to create a single color fill. So, how might I loop through colors and assign a gradient fill based off a separate value?
Thanks so much for your help! Let me know if I can clarify

Using d3.js v4 - using parentId to resolve ambiguity

I am trying to understand the right usage to achieve my collapsible tree d3 but unable to establish the proper parent/child references since I cannot use "parent". Attempting to use parentID.
This is my dataset I am testing with:
var result = [
{ "id": 1, "name": "Top Level", "parent": null, "parentId": "" },
{ "id": 2, "name": "PROD", "parent": "Top Level", "parentId": 1 },
{ "id": 3, "name": "QAT", "parent": "Top Level", "parentId": 1 },
{ "id": 4, "name": "App1", "parent": "PROD", "parentId": 2 },
{ "id": 5, "name": "App1", "parent": "QAT", "parentId": 3 },
{ "id": 6, "name": "ServerPROD001", "parent": "App1", "parentId": 4 },
{ "id": 7, "name": "ServerQAT001", "parent": "App1", "parentId": 5 }
];
and based on the collapsible tree:
// convert the flat data into a hierarchy
var treeData = d3.stratify()
.id(function (d) { return d.name; })
.parentId(function (d) { return d.parent })
(result);
This works fine if I do not include items 6 and 7. If I do include these I get an ambiguity error which makes sense because it cannot determine which "App1" to associate to.
I tried changing the code to use the parentId but just get an error of "missing:1" now.
// convert the flat data into a hierarchy
var treeData = d3.stratify()
.id(function (d) { return d.name; })
.parentId(function (d) { return d.parentId })
(result);
Note - I cannot change the "App1" name values to something unique as they will exist in multiple areas with that given name.
Since you have the id that is unique and not the name:
// convert the flat data into a hierarchy
var treeData = d3.stratify()
.id(function (d) { return d.id; }) // return the id instead of the name
.parentId(function (d) { return d.parentId })
(result);
and then set the name you need to be displayed like this:
// assign the name to each node as the initial name
treeData.each(function(d) {
d.name = d.data.name;
});
A working example can be found here, based on this
:)
Good luck!

How to use nest and rollup functions in D3 to create a bar chart

I'm new to D3 and struggling understand the nest function. I'm trying to get it working to produce a bar chart that will have three different bars for the years '2013', '2014' and '2015' and the length of each bar to be the number of entries for that year.
I've looked at lots of examples, but I'm missing some of the steps. I'd like to know how to view / troubleshoot what nest does to my data (listing keys and values etc.) And I'd also like to know how to utilise the data in a simple bar chart (what data do I call and what do I return for 'height' etc.)
I have made a fiddle here http://jsfiddle.net/hellococomo/zz81pwkm/4/ but can't figure out why I can't get any height on the bars. I'd really appreciate any help.
This is my example code:
var fruit = [
{"name": "Apple", "year": 2013, "win": "1"},
{"name": "Banana", "year": 2013, "win": "1"},
{"name": "Orange", "year": 2013, "win": "1"},
{"name": "Grapefruit", "year": 2013, "win": "0"},
{"name": "Grape", "year": 2014, "win": "0"},
{"name": "Pineapple", "year": 2014, "win": "1"},
{"name": "Melon", "year": 2014, "win": "1"},
{"name": "Grape", "year": 2014, "win": "1"},
{"name": "Pineapple", "year": 2014, "win": "1"},
{"name": "Pineapple", "year": 2015, "win": "1"},
];
data = d3.nest()
.key(function(d){ return d.year }) // `GROUP BY date`
.rollup(function(values){
// `values` is all the rows of a particular date
var counts = {}, keys = ['name', 'win']
keys.forEach(function(key){
counts[key] = d3.sum(values, function(d){ return d[key] })
})
return counts
})
.entries(fruit)
var svg =
d3.select('svg g')
.selectAll('rect')
.data(data)
.enter();
svg.append('rect')
.attr('x', function(d, i) {return i * 60 })
.attr('y', 50)
.attr('width', 50)
.attr('height', function(d) { return d['win'] })
.style('fill', 'steelblue');
Check this out: http://jsfiddle.net/yojm65nk/7/
.rollup(function(values){
// `values` is all the rows of a particular date
var counts = {}; var keys = ['name', 'win']
values.forEach(function(d){
for (var i = 0; i<keys.length; i++) {
counts[keys[i]] = d3.sum(values, function(d){ return d[keys[i]] })
}
Basically in your nest function, especially in your roll up you need to iterate through the data to expose your data variables. Once you have that you can draw you bar graph accordingly.
If you log the value of each of the Objects in your data (for example, using the Console in Chrome), you'll see that the Objects do not have a "win" property.
{"key":"2013","values":{"name":0,"win":3}}
As a result, the height of the <rect>s is not being set correctly (all of them are being set to null).
However, you can also see that you can access the "win" property of your data through the "values" Object:
.attr('height', function(d) { return d.values.win }) // <---- access .values first!
which will set the "height" according to the "wins" value in fruit.

Parsing errors when i try to create pie chart using d3js

I am trying to create pie charts using d3js. I dont face any issues when i used simple json file. But later when i tried to use slightly more complex json, i am getting these 2 errors.
Error: Problem parsing d="M0,-300A300,300 0 1,1 NaN,NaNLNaN,NaNA20,20 0 1,0 0,-20Z"
Error: Problem parsing d="MNaN,NaNA300,300 0 1,1 NaN,NaNLNaN,NaNA20,20 0 1,0 NaN,NaNZ"
from my understanding the error is at arcs.append("path").attr("d", arc). but donno how to fix it.
here is the d3js code
<div id="sample1">
<script>
var r = 300;
var color = d3.scale.category10()
var canvas = d3.select("#sample1").append("svg")
.attr("width", 700)
.attr("height", 700);
var group = canvas.append("g")
.attr("transform", "translate(350,350)");
var arc = d3.svg.arc()
.innerRadius(20)
.outerRadius(r);
var pie = d3.layout.pie()
.value(function(d) {
d.children.forEach(function(x) {
return x.value;
});
})
.sort(null);
d3.json("js/mydata.json", function(data) {
var arcs = group.selectAll(".arc")
.data(pie(data.children))
.enter()
.append("g")
.attr("class", "arc");
arcs.append("path")
.attr("d", arc)
.attr("fill", function(d) {
d.data.children.forEach(function(x) {
return color(x.name);
});
});
})
</script>
</div>
here is my json
{
"name": "All",
"children": [
{
"name": "Main1",
"children": [
{
"name": "Sub1",
"value": 6.25
},
{
"name": "Sub2",
"value": 12.50
},
{
"name": "Sub3",
"value": 6.25
}
]
},
{
"name": "Main2",
"children": [
{
"name": "Sub4",
"value": 6.25
},
{
"name": "Sub5",
"value": 12.50
},
{
"name": "Sub6",
"value": 6.25
}
]
},
{
"name": "Main3",
"children": [
{
"name": "Sub7",
"value": 6.25
},
{
"name": "Sub8",
"value": 12.50
},
{
"name": "Sub9",
"value": 6.25
}
]
},
{
"name": "Main4",
"children": [
{
"name": "Sub10",
"value": 6.25
},
{
"name": "Sub11",
"value": 12.50
},
{
"name": "Sub12",
"value": 6.25
}
]
}
]
}
Updated:
The approach given by "Lars Kotthoff" worked. how ever this approach does not fix my actual problem which i dint mentioned here. The problem is, i want to give a border to all the Main1,Main2,Main3,Main4. it means although there are 12 colors here borders will be only 4 i.e grouping all three colors into one based on ite parent.
Below picture shows my requirement.

Hyperlinks in d3.js objects

I am a complete novice at d3.js or java in general. I am using the indented tree example from http://bl.ocks.org/1093025. It took me two hours to get this to work on my local computer, so that should give you an idea of my skill level.
I opened the flare.json file and started messing with it and was able to manipulate it successfully. It looks like this
{
"name": "Test D3",
"children": [
{
"name": "News",
"children": [
{
"name": "CNN",
"size": 1000
},
{
"name": "BBC",
"size": 3812
}
]
},
{
"name": "Blogs",
"children": [
{
"name": "Engaget",
"size": 3938
}
]
},
{
"name": "Search",
"children": [
{
"name": "Google",
"size": 3938
},
{
"name": "Bing",
"size": 3938
}
]
}
]
}
What I want to do now, is to try to add hyperlinks. For example, I want to be able to click on "CNN" and go to CNN.com. Is there a modification I can make to flare.json that will do that?
It is quite easy, just add some more "key" : "value" pairs. Example:
"children": [
{
"name": "Google",
"size": 3938,
"url": "https://www.google.com"
},
{
"name": "Bing",
"size": 3938,
"url": "http://www.bing.com"
}
]
Of course, in your d3 code you then need to append <svg:a> tags and set their xlink:href attribute.
Here is some html and d3-code that might be of help to you. First you need to import the xlink namespace in your html file:
<html xmlns:xlink="http://www.w3.org/1999/xlink">
...
</html>
Then in the d3 drawing code where you append nodes for each data element you wrap the element you want to be clickable links with an svg:a tag:
nodeEnter.append("svg:a")
.attr("xlink:href", function(d){return d.url;}) // <-- reading the new "url" property
.append("svg:rect")
.attr("y", -barHeight / 2)
.attr("height", barHeight)
.attr("width", barWidth)
.style("fill", color)
.on("click", click); // <- remove this if you like
You might want to remove the click handler (which is present in the original example) by deleting the .on("click", click) as it might interfere with the default behavior of SVG links.
Clicking on your rects should now lead you to the appropriate url.
SVG links might not be fully implemented in all browsers.
Alternatively you could modify the click handler to read the URL from d.url and use that one to manually redirect the browser to that URL via JavaScript: window.location = d.url;. Then you do not need the svg:a tag and the xlink code. Though adding a real link (not a scripted one) has the benefit that the user/browser can decide what to do (e.g., open in new tab/page). It also helps if some of your users have JavaScript disabled.

Resources