D3 barplot only using half my data - javascript

I have a d3.js barplot using some json data containing 12 elements. The data value I'm using for bar height is fpkm. I'm able to return that value as a callback to d3's data function- but only for half the elements.
My problem is that only the first half of the values are appearing in my barplot. I only get 6 rows corresponding to my first 6 values.
I made a fiddle here: http://jsfiddle.net/z9Mvt/
I can't seem to figure out why it's only using half the elements in my json.
Any help = appreciated.
html:
<div align='center' id="GECGplot" style='width:98%;text-align:center;'></plot>
and the js:
var gecgData= {"nodeName":"GECG","children":[{"nodeName":0,"nodeData":{"id":"643139","library_id":"SI_5589","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"1.1241","fpkm_conf_lo":"0.898502","fpkm_conf_hi":"1.34969","fpkm_status":"OK","fpkm_percentile_compendium":"8.33","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":1,"nodeData":{"id":"872561","library_id":"SI_5596","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"1.12666","fpkm_conf_lo":"0.871059","fpkm_conf_hi":"1.38226","fpkm_status":"OK","fpkm_percentile_compendium":"16.67","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":2,"nodeData":{"id":"1031623","library_id":"SI_5553","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"1.21305","fpkm_conf_lo":"0.949369","fpkm_conf_hi":"1.47674","fpkm_status":"OK","fpkm_percentile_compendium":"25.00","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":3,"nodeData":{"id":"248423","library_id":"SI_5486","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"1.98203","fpkm_conf_lo":"1.64888","fpkm_conf_hi":"2.31519","fpkm_status":"OK","fpkm_percentile_compendium":"33.33","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":4,"nodeData":{"id":"1039674","library_id":"SI_5554","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"2.24514","fpkm_conf_lo":"1.83333","fpkm_conf_hi":"2.65696","fpkm_status":"OK","fpkm_percentile_compendium":"41.67","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":5,"nodeData":{"id":"304849","library_id":"SI_5485","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"2.29868","fpkm_conf_lo":"2.02514","fpkm_conf_hi":"2.57221","fpkm_status":"OK","fpkm_percentile_compendium":"50.00","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":6,"nodeData":{"id":"417495","library_id":"SI_5484","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"2.61196","fpkm_conf_lo":"2.28949","fpkm_conf_hi":"2.93442","fpkm_status":"OK","fpkm_percentile_compendium":"58.33","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":7,"nodeData":{"id":"928522","library_id":"SI_5595","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"2.94397","fpkm_conf_lo":"2.61962","fpkm_conf_hi":"3.26832","fpkm_status":"OK","fpkm_percentile_compendium":"66.67","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":8,"nodeData":{"id":"622876","library_id":"SI_5552","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"3.27303","fpkm_conf_lo":"2.79509","fpkm_conf_hi":"3.75097","fpkm_status":"OK","fpkm_percentile_compendium":"75.00","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":9,"nodeData":{"id":"50230","library_id":"SI_5487","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"9.88611","fpkm_conf_lo":"8.6495","fpkm_conf_hi":"11.1227","fpkm_status":"OK","fpkm_percentile_compendium":"83.33","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":10,"nodeData":{"id":"816444","library_id":"SI_5594","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"15.1868","fpkm_conf_lo":"13.8218","fpkm_conf_hi":"16.5519","fpkm_status":"OK","fpkm_percentile_compendium":"91.67","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}},
{"nodeName":11,"nodeData":{"id":"496931","library_id":"SI_5551","gene_id":"ENSG00000157554","gene_short_name":"ERG","fpkm":"52.249","fpkm_conf_lo":"50.8217","fpkm_conf_hi":"53.6763","fpkm_status":"OK","fpkm_percentile_compendium":"100.00","chr_id":"21","start":"39751948","end":"40033704","locus":"21:39751948-40033704","report":"0","tracking_id":null,"class_code":null,"nearest_ref":null,"tss_id":null,"length":null,"coverage":null,"fpkm_percentile_origin_tissue":null,"fpkm_percentile_collection_tissue":null,"fpkm_percentile_sample_cancer":null,"fpkm_fold_change_benign":null}}]}
;
//Width and height
// var w = $('#GECGplot').width();
var w = 700;
var h = 300;
var barPadding = 1;
var margin = {top: 40, right: 10, bottom: 20, left: 10};
var xScale = d3.scale.linear().
domain([0, 20]). // your data minimum and maximum
range([0, h]); // the pixels to map to, e.g., the width of the diagram.
//Create SVG element
var svg = d3.select("#GECGplot")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
// .data(dataset)
.data(function(d, i) {
return plotData[i].nodeData.fpkm;
})
.enter()
.append("rect")
.attr("x", function(d, i) {
// alert(plotData.length);
return i * (w / plotData.length);
})
.attr("y", function(d, i) {
alert(plotData[i].nodeData.fpkm);
return h - (plotData[i].nodeData.fpkm * 50); //Height minus data value
})
.attr("width", w / plotData.length - barPadding)
.attr("height", function(d, i) {
return plotData[i].nodeData.fpkm * 50; //Just the data value
})
.attr("fill", function(d, i) {
return "rgb(0, 0, " + (plotData[i].nodeData.fpkm * 50) + ")";
})
svg.selectAll("text")
.data(function(d, i) {
return plotData[i].nodeData.fpkm;
})
.enter()
.append("text")
.text(function(d, i) {
return plotData[i].nodeData.fpkm;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white")
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return i * (w / plotData.length) + (w / plotData.length - barPadding) / 2;
})
.attr("y", function(d, i) {
return h - (plotData[i].nodeData.fpkm * 50) + 14;
})
// alert(tableSchema);

Here you go. You bind the array "children" to the rectangle elements so you dont need the argument 'i' to access the value you need.
Also, I would recommend using the d3.scale.ordinal() for your x axis as opposed to calculating it explicitly from the data. Litte more flexible.
http://jsfiddle.net/Cef4D/
svg.selectAll("rect")
.data(plotData)
.enter().append("rect")
.attr("x", function(d, i) {return i * (w / plotData.length);})
.attr("y", function(d) {
return h - (d.nodeData.fpkm * 50); //Height minus data value
})
.attr("width", w / plotData.length - barPadding)
.attr("height", function(d, i) {
return d.nodeData.fpkm * 50; //Just the data value
})
.attr("fill", function(d, i) {
return "rgb(0, 0, " + (d.nodeData.fpkm * 50) + ")";
})

Related

D3 text-anchor won't append

var w = 300;
var h = 150;
var padding = 2;
var dataset =[5, 10, 15, 20, 25];
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
function colorPicker(v){
if (v<=20) { return "#666666"; }
else if (v>20) { return "#FF0033"; }
}
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) { return (i*(w/dataset.length)); })
.attr("y", function(d) { return h-(d*4); })
.attr("width", w/dataset.length-padding)
.attr("height", function(d) { return d*4;})
.attr("fill", function(d){
return colorPicker(d);
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {return d; })
.attr({"text-anchor": "middle"})
.attr({
x: function(d, i) {return i* (w / dataset.length);},
y: function(d) {return h - (d*4); }
});
I am following a D3.js tutorial and I'm trying to get the text-anchor to work, but it won't append. No text appears, can anyone shed any light into what I'm doing wrong?
It should display the number above every rectangle
In the new (not so new, actually) V4.x version, you cannot use objects to set the attr() method.
Besides that you have another problem, which will avoid the texts to be rendered: there is no value property in your dataset (which is just an array of numbers). Thus, it should be:
.text(function(d){return d})
Here is your code with the necessary changes:
var w = 300;
var h = 150;
var padding = 2;
var dataset = [5, 10, 15, 20, 25];
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
function colorPicker(v) {
if (v <= 20) {
return "#666666";
} else if (v > 20) {
return "#FF0033";
}
}
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return (i * (w / dataset.length));
})
.attr("y", function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - padding)
.attr("height", function(d) {
return d * 4;
})
.attr("fill", function(d) {
return colorPicker(d);
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("text-anchor", "middle")
.text(function(d) {
return d;
})
.attr("x", function(d, i) {
return i * (w / dataset.length) + ((w / dataset.length - padding) / 2);
})
.attr("y", function(d) {
return h - (d * 4);
});
<script src="https://d3js.org/d3.v4.min.js"></script>

data not bind from json for d3 chart

Hi I am using D3 chart.
i'm using This d3 chart :http://bl.ocks.org/diethardsteiner/3287802
In this chart all the data are read from variable. I want to read the data from json file.
I have complete the half of the work. I did same to complete the another half of the work but it is not working.
Pie chart is read data from json. but the bar chart is not to read data from json.
Here I have Created Plunker check this and give some solution.
https://plnkr.co/edit/TaXMsUWuIXe5kv3yzazk?p=preview
here what i tried to read data is not read from json.
I want to run this chart as same as this example:http://bl.ocks.org/diethardsteiner/3287802
i tried like this
d3.json("data1.json", function(datasetBarChart){
debugger;
// set initial group value
var group = "All";
function datasetBarChosen(group) {
var ds = [];
for (x in datasetBarChart) {
if(datasetBarChart[x].group==group){
ds.push(datasetBarChart[x]);
}
}
return ds;
}
function dsBarChartBasics() {
debugger;
var margin = {top: 30, right: 5, bottom: 20, left: 50},
width = 500 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom,
colorBar = d3.scale.category20(),
barPadding = 1
;
return {
margin : margin,
width : width,
height : height,
colorBar : colorBar,
barPadding : barPadding
}
;
}
function dsBarChart() {
debugger;
var firstDatasetBarChart = datasetBarChosen(group);
var basics = dsBarChartBasics();
var margin = basics.margin,
width = basics.width,
height = basics.height,
colorBar = basics.colorBar,
barPadding = basics.barPadding
;
var xScale = d3.scale.linear()
.domain([0, firstDatasetBarChart.length])
.range([0, width])
;
var yScale = d3.scale.linear()
.domain([0, d3.max(firstDatasetBarChart, function(d) { return d.measure; })])
.range([height, 0])
;
//Create SVG element
var svg = d3.select("#barChart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id","barChartPlot")
;
var plot = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
;
plot.selectAll("rect")
.data(firstDatasetBarChart)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("width", width / firstDatasetBarChart.length - barPadding)
.attr("y", function(d) {
return yScale(d.measure);
})
.attr("height", function(d) {
return height-yScale(d.measure);
})
.attr("fill", "lightgrey")
;
// Add y labels to plot
plot.selectAll("text")
.data(firstDatasetBarChart)
.enter()
.append("text")
.text(function(d) {
return formatAsInteger(d3.round(d.measure));
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return (i * (width / firstDatasetBarChart.length)) + ((width / firstDatasetBarChart.length - barPadding) / 2);
})
.attr("y", function(d) {
return yScale(d.measure) + 14;
})
.attr("class", "yAxis")
var xLabels = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + (margin.top + height) + ")")
;
debugger;
xLabels.selectAll("text.xAxis")
.data(firstDatasetBarChart)
.enter()
.append("text")
.text(function(d) { return d.category;})
.attr("text-anchor", "middle")
// Set x position to the left edge of each bar plus half the bar width
.attr("x", function(d, i) {
return (i * (width / firstDatasetBarChart.length)) + ((width / firstDatasetBarChart.length - barPadding) / 2);
})
.attr("y", 15)
.attr("class", "xAxis")
//.attr("style", "font-size: 12; font-family: Helvetica, sans-serif")
;
// Title
svg.append("text")
.attr("x", (width + margin.left + margin.right)/2)
.attr("y", 15)
.attr("class","title")
.attr("text-anchor", "middle")
.text("Elevator Trips by Material Stream and Destination")
;
}
dsBarChart();
/* ** UPDATE CHART ** */
/* updates bar chart on request */
function updateBarChart(group, colorChosen) {
debugger;
var currentDatasetBarChart = datasetBarChosen(group);
var basics = dsBarChartBasics();
var margin = basics.margin,
width = basics.width,
height = basics.height,
colorBar = basics.colorBar,
barPadding = basics.barPadding
;
var xScale = d3.scale.linear()
.domain([0, currentDatasetBarChart.length])
.range([0, width])
;
var yScale = d3.scale.linear()
.domain([0, d3.max(currentDatasetBarChart, function(d) { return d.measure; })])
.range([height,0])
;
var svg = d3.select("#barChart svg");
var plot = d3.select("#barChartPlot")
.datum(currentDatasetBarChart)
;
/* Note that here we only have to select the elements - no more appending! */
plot.selectAll("rect")
.data(currentDatasetBarChart)
.transition()
.duration(750)
.attr("x", function(d, i) {
return xScale(i);
})
.attr("width", width / currentDatasetBarChart.length - barPadding)
.attr("y", function(d) {
return yScale(d.measure);
})
.attr("height", function(d) {
return height-yScale(d.measure);
})
.attr("fill", colorChosen)
;
plot.selectAll("text.yAxis") // target the text element(s) which has a yAxis class defined
.data(currentDatasetBarChart)
.transition()
.duration(750)
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return (i * (width / currentDatasetBarChart.length)) + ((width / currentDatasetBarChart.length - barPadding) / 2);
})
.attr("y", function(d) {
return yScale(d.measure) + 14;
})
.text(function(d) {
return formatAsInteger(d3.round(d.measure));
})
.attr("class", "yAxis")
;
svg.selectAll("text.title") // target the text element(s) which has a title class defined
.attr("x", (width + margin.left + margin.right)/2)
.attr("y", 15)
.attr("class","title")
.attr("text-anchor", "middle")
.text(group + "'s Elevator Trips by Material Stream and Destination")
;
}
});
Thanks,
You are using wrong d3.json callback signature. The first argument of the callback is an error that occurred, or null if no error occurred, the second argument is the returned data. So, you should use following:
d3.json("data1.json", function(error, data){
if(error) {
// handle error
} else {
// work with the data array
}
}
The following code snippet demonstrates the loading of dataset from an external JSON storage. When data has been loaded it is passed to the dsPieChart function that draws the above mentioned pie chart.
d3.select(window).on('load', function() {
// Loading data from external JSON source
d3.json('https://api.myjson.com/bins/1hewit', function(error, json) {
if (error) {
throw new Error('An error occurs');
} else {
dsPieChart(json);
}
});
});
// Format options
var formatAsPercentage = d3.format("%"),
formatAsPercentage1Dec = d3.format(".1%"),
formatAsInteger = d3.format(","),
fsec = d3.timeFormat("%S s"),
fmin = d3.timeFormat("%M m"),
fhou = d3.timeFormat("%H h"),
fwee = d3.timeFormat("%a"),
fdat = d3.timeFormat("%d d"),
fmon = d3.timeFormat("%b");
// PIE CHART drawing
function dsPieChart(dataset) {
var width = 400,
height = 400,
outerRadius = Math.min(width, height) / 2,
innerRadius = outerRadius * .999,
innerRadiusFinal = outerRadius * .5,
innerRadiusFinal3 = outerRadius * .45,
color = d3.scaleOrdinal(d3.schemeCategory20);
var vis = d3.select("#pieChart")
.append("svg:svg")
.data([dataset])
.attr("width", width)
.attr("height", height)
.append("svg:g")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
var arc = d3.arc()
.outerRadius(outerRadius).innerRadius(innerRadius);
var arcFinal = d3.arc().innerRadius(innerRadiusFinal).outerRadius(outerRadius);
var arcFinal3 = d3.arc().innerRadius(innerRadiusFinal3).outerRadius(outerRadius);
var pie = d3.pie()
.value(function(d) {
return d.measure;
});
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("svg:g")
.attr("class", "slice")
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", up);
arcs.append("svg:path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc)
.append("svg:title")
.text(function(d) {
return d.data.category + ": " + formatAsPercentage(d.data.measure);
});
d3.selectAll("g.slice").selectAll("path").transition()
.duration(750)
.delay(10)
.attr("d", arcFinal);
arcs.filter(function(d) {
return d.endAngle - d.startAngle > .2;
})
.append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + arcFinal.centroid(d) + ")rotate(" + angle(d) + ")";
})
.text(function(d) {
return d.data.category;
});
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
vis.append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text("Revenue Share 2012")
.attr("class", "title");
function mouseover() {
d3.select(this).select("path").transition()
.duration(750)
.attr("d", arcFinal3);
}
function mouseout() {
d3.select(this).select("path").transition()
.duration(750)
.attr("d", arcFinal);
}
function up(d, i) {
updateBarChart(d.data.category, color(i));
updateLineChart(d.data.category, color(i));
}
}
#pieChart {
position: absolute;
top: 10px;
left: 10px;
width: 400px;
height: 400px;
}
.slice {
font-size: 12pt;
font-family: Verdana;
fill: white;
font-weight: bold;
}
.title {
font-family: Verdana;
font-size: 15px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="pieChart"></div>
See also Bar chart from external JSON file example.

d3 Bar Chart append text to bar

I've followed the tutorial to make a bar chart from Scott Murray from alignedleft. I'm having problem with my dataset and adding the dataset to a bar as text.
The image below: 1 bar chart: from the tutorial , 2nd bar chart: how I want to display the text.
Here's my code so far:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial d3 bar chart!</title>
<script type="text/javascript" src="d3/d3.v3.js"></script>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 100;
var i = 0;
var barPadding = 1;
var dataset = [
{key:"Department1", value:6234490},
{key:"Department 2", value:9700},
{key:"Department 3", value:2954},
];
//Width and height
var w = 500;
var h = 100;
var barPadding = 1;
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d) {
return d * 4;
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
for(int i = 0; i < dataset.length; i++){
return d[i].key;
}
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
})
.attr("y", function(d) {
return h - (d * 4) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");
</script>
</body>
</html>
I've tried to add the text in this part:
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
for(int i = 0; i < dataset.length; i++){
return d[i].key;
}
})
But that just gives me this error:
I hope you guys can help me out.
Try changing int to var, int doesn't exist in javascript.
Every function in d3js provides access to data and the index.
Just use this
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d){return d.key;}
})
EDIT
svg.selectAll("g")
.data(dataset)
.enter()
.append("g")
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d) {
return d * 4;
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
})
.append("text")
.text(function(d) {
return d.key;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
})
.attr("y", function(d) {
return h - (d * 4) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");

D3 - How to loop through an object with keys for a bar chart

I am trying to create a bar chart with the dataset below. I am stuck on the part where the height[score] of the bar[country] is determined. How do I loop through the dataset to pull each score for a different country?
Any help would be greatly appreciated :)
var w = 500;
var h = 100;
var barPadding = 1;
var dataset = [
{"country":"Hong Kong","score":8.98},
{"country":"Singapore","score":8.54},
{"country":"New Zealand","score":8.19},
{"country":"Switzerland","score":8.09},
{"country":"Mauritius","score":8.98},
{"country":"United Arab Emirates","score":8.05},
{"country":"Canada","score":8.00},
{"country":"Australia","score":7.87},
{"country":"Jordan","score":7.86},
{"country":"Chile","score":7.84},
];
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d) {
return d * 4;
});
In D3, once you load the data through the .data(dataset) command, you can now access each record of the data by inserting the anonymous function function(d, i) { } as you have done in a few of your attributes.
Since your dataset is:
var dataset = [
{"country":"Hong Kong","score":8.98},
{"country":"Singapore","score":8.54},
{"country":"New Zealand","score":8.19},
{"country":"Switzerland","score":8.09},
{"country":"Mauritius","score":8.98},
{"country":"United Arab Emirates","score":8.05},
{"country":"Canada","score":8.00},
{"country":"Australia","score":7.87},
{"country":"Jordan","score":7.86},
{"country":"Chile","score":7.84},
];
each d is a object record e.g. {"country":"Singapore","score":8.54}, while i refers to the index of the object d returned e.g. 1 for our example of d used above.
To access the score of the object record d, this becomes simple Javscript object notation i.e. d.score.
Hence your .attr call should look like:
.attr("height", function(d) {
return d.score * 4;
});
Similarly, you can extract the other fields e.g. country with d.country if you intend to use it in .attr("text", function(d) { return d.country; });
This is the real beauty and power of D3. If you ever want to expand your visualization with more features that is obtained through your data, then all you have to make sure is that your dataset data contains more data attributes, and you can call them later as you iterate through the anonymous functions. And D3 is in the spirit of its name, truly being "data-driven"! :)
You will need to fix d to d.score.
If you want to show country text, write svg.selectAll("text") after svg.selectAll("rect").
Like this:
var w = 500;
var h = 100;
var barPadding = 1;
var dataset = [
{"country":"Hong Kong","score":8.98},
{"country":"Singapore","score":8.54},
{"country":"New Zealand","score":8.19},
{"country":"Switzerland","score":8.09},
{"country":"Mauritius","score":8.98},
{"country":"United Arab Emirates","score":8.05},
{"country":"Canada","score":8.00},
{"country":"Australia","score":7.87},
{"country":"Jordan","score":7.86},
{"country":"Chile","score":7.84},
];
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return h - (d.score * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d) {
return d.score * 4;
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d.country;
})
.attr("transform", function(d, i) {
var barW = w / dataset.length;
return "translate(" +
( barW * i + barW / 2 + barPadding ) + "," +
( h - 5 ) +
")rotate(-90)";
})
.attr("font-size", "8pt")
.attr("fill", "white");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Something like
For( var i =0; i<dataset.length; i++){
// Dataset[i].country
// dataset[i].score
}
You have an array of objects

Donut chart in d3

i have donut chart with legend specification. I have 2 values in dataset. But here with this code i'm getting only the first value, "Unresolved".
var dataset = {
Unresolved: [3],
Resolved:[7]
};
var keyValue=[];
for(key in dataset){
keyValue.push(key);
}
var width = 260,
height = 300,
radius = Math.min(width, height) / 2;
var color = ["#9F134C", "#ccc"];
var pie = d3.layout.pie()
.sort(null);
var arc = d3.svg.arc()
.innerRadius(radius - 90)
.outerRadius(radius - 80);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g");
var path = gs.selectAll("path")
.data(function(d,i) { return pie(d); })
.enter().append("path")
.attr("fill", function(d, i) { console.log("log", keyValue[i]);return color[i]; }) //Here i'm getting only the 1st value "unresolved".
.attr("d", arc);
var legendCircle = d3.select("body").append("svg").selectAll("g").data(keyValue).enter().append("g")
.attr("class","legend")
.attr("width", radius)
.attr("height", radius * 2)
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legendCircle.append("rect")
.attr("width", 18)
.attr("height", 10)
.style("fill", function(d, i) { return color[i];});
legendCircle.append("text")
.attr("x", 24)
.attr("y", 5)
.attr("dy", ".35em")
.text(function(d) { return d; });
The output i'm getting is,
Can anyone help on this? Thanks.
It looks like you're doing a nested selection in your code, which you would usually only need for nested data. Your data is not nested however -- there's a single level with 2 values. What's happening is that, by using a nested selection, you're descending into the value arrays, each of which contains only a single value.
It works fine if you do away with the nested selection and pass your original data to the pie layout.
var gs = svg.selectAll("g").data(pie(d3.values(dataset))).enter().append("g");
var path = gs.append("path")
.attr("fill", function(d, i) { return color[i]; })
.attr("d", arc);
Complete example here.

Categories