I've made a pie-chart and trying to display it on a page using require.js but can't do it correctly. Firebug shows that there is svg on this page with certain size and the page is empty. I tried to implement other moodules - they work well.
File main.js:
require.config({
paths: {
'd3': "http://d3js.org/d3.v3.min"
},
shim: {
'd3': {exports:'d3'}
}
});
require([
'd3',
'pie-chart'
], function (d3, piechart) {
d3.select("body").append("h1").text("Successfully loaded D3 version " + d3.version);
d3.select("body").append("svg");
});
File pie-chart.js:
define('pie-chart', function () {
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var legendRectSize = 18;
var legendSpacing = 4;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var percentageFormat = d3.format("%");
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.values;
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.json("staff.json", function(error, json_data) {
var data = d3.nest()
.key(function(d) {
return d.Position;
})
.rollup(function(d) {
return d.length;
}).entries(json_data);
data.forEach(function(d) {
d.percentage = d.values / json_data.length;
});
console.log(data)
console.log("data variable", data);
console.log("pie(data)", pie(data));
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc")
.on('mouseover', function() {
var current = this;
var others = svg.selectAll(".arc").filter(function(el) {
return this != current
});
others.selectAll("path").style('opacity', 0.8);
})
.on('mouseout', function() {
var current = this;
d3.select(this)
.style('opacity', 1);
var others = svg.selectAll(".arc").filter(function(el) {
return this != current
});
others.selectAll("path").style('opacity', 1);
});
g.append("path")
.attr("d", arc)
.style("fill", function(d, i) {
return color(d.data.key);
});
g.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) {
console.log("d is", d);
return percentageFormat(d.data.percentage);
});
var legend = d3.select("body").append("svg")
.attr("class", "legend")
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) {
return color(d.key);
});
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text(function(d) { return d.key; });
});
});
File d3.js I wrapped this way:
define('d3', function () {
// require.js code
});
d3 is not dependent on JQuery. I removed the jquery from your plunk, also you do not need the shim attribute. Your main.js should be something like this:
require.config({
paths: {
'd3': "https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.9/d3.min"
}
});
require([
'd3',
'pie-chart'
], function ( d3, $, piechart) {
});
Here is the working plunk link: http://plnkr.co/edit/Le4tpejMvPxLA08isacW?p=preview
Related
I create a bubble map with D3, and I want the user to be able to click on a button and the circles on the map will transition into bars of a bar chart. I am using the enter, update, exit pattern, but right now what I have isn't working as the bar chart is drawn on top and all the bars and circles are translated, instead of the circles transitioning into bars and the bars being translated into place. Below is the relevant part of my code, and here is the link to the demo: https://jhjanicki.github.io/circles-to-bars/
var projection = d3.geo.mercator()
.scale(150)
.center([20, 40])
.translate([width / 2, height / 2]);
var path= d3.geo.path()
.projection(projection);
var features = countries2.features;
d3.csv("data/sum_by_country.csv", function(error, data) {
data.sort(function(a,b){
return a.value - b.value;
});
var myfeatures= joinData(features, data, ['value']);
var worldMap = svg.append('g');
var world = worldMap.selectAll(".worldcountries")
.data(myfeatures)
.enter()
.append("path")
.attr("class", function(d){
return "World " + d.properties.name+" worldcountries";
})
.attr("d", path)
.style("fill", "#ddd")
.style("stroke", "white")
.style("stroke-width", "1");
var radius = d3.scale.sqrt()
.domain([0,1097805])
.range([3, 20]);
var newFeatures = [];
myfeatures.forEach(function(d){
if(d.properties.hasOwnProperty("value")){
console.log(d.properties.name);
newFeatures.push(d);
}
});
newFeatures.sort(function(a,b){
return b.properties.value - a.properties.value;
});
var bubbles = svg.append("g").classed("bubbleG","true");
bubbles.selectAll("circle")
.data(newFeatures)
.enter().append("circle")
.attr("class", "bubble")
.attr("transform", function(d) {
return "translate(" + path.centroid(d) + ")";
})
.attr("r", function(d){
return radius(d.properties.value);
})
.attr("fill","#2166ac")
.attr("stroke","white")
.attr("id", function(d){
return "circle "+d.properties.name;
});
$('#bubblebar').click(function(){
mapBarTransition(newFeatures,bubbles)
});
});
// button onclick
function mapBarTransition(data,bubbles){
var margin = {top:20, right:20, bottom:120, left:80},
chartW = width - margin.left - margin.right,
chartH = height - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.domain(data.map(function(d) { return d.properties.name; }))
.rangeRoundBands([0, chartW], .4);
var y = d3.scale.linear()
.domain([0,1097805])
.nice()
.range([chartH,0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.ticks(8)
.orient("left");
var barW = width / data.length;
bubbles.append("g").classed("bubblebar-chart-group", true);
bubbles.append("g").classed("bubblebar-x-axis-group axis", true);
bubbles.append("g").classed("bubblebar-y-axis-group axis", true);
bubbles.transition().duration(1000).attr({transform: "translate(" + margin.left + "," + margin.top + ")"});
bubbles.select(".bubblebar-x-axis-group.axis")
.attr({transform: "translate(0," + (chartH) + ")"})
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
bubbles.select(".bubblebar-y-axis-group.axis")
.transition()
.call(yAxis);
barW = x.rangeBand();
var bars = bubbles.select(".bubblebar-chart-group")
.selectAll(".bubble")
.data(data);
bars.enter().append("rect")
.classed("bubble", true)
.attr("x", function(d) { return x(d.properties.name); })
.attr("y", function(d) { return y(d.properties.value); })
.attr("width", barW)
.attr("height", function(d) { return chartH - y(d.properties.value); })
.attr("fill","#2166ac");
bars.transition()
.attr("x", function(d) { return x(d.properties.name); })
.attr("y", function(d) { return y(d.properties.value); })
.attr("width", barW)
.attr("height", function(d) { return chartH - y(d.properties.value); });
bars.exit().transition().style({opacity: 0}).remove();
}
And here is the repo for your reference: https://github.com/jhjanicki/circles-to-bars
First, you have two very different selections with your circles and bars. They are in separate g containers and when you draw the bar chart, you aren't even selecting the circles.
Second, I'm not sure that d3 has any built-in way to know how to transition from a circle element to a rect element. There's some discussion here and here
That said, here's a quick hack with your code to demonstrate one way you could do this:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel='stylesheet'>
<link href="//rawgit.com/jhjanicki/circles-to-bars/master/css/style.css" rel='stylesheet'>
<!-- Roboto & Asar CSS -->
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/css?family=Asar" rel="stylesheet">
</head>
<body>
<button type="button" class="btn btn-primary" id="bubblebar">Bar Chart</button>
<div id="chart"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<!-- D3.geo -->
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//rawgit.com/jhjanicki/circles-to-bars/master/data/countries2.js"></script>
<script>
window.onload = function() {
// set up svg and scrolling
var width = window.innerWidth / 2;
var height = window.innerHeight;
var svg = d3.select("#chart").append("svg")
.attr('width', width)
.attr('height', height);
var bubbleMapState = 'map'; // map or bar
var projection = d3.geo.mercator()
.scale(150)
.center([20, 40])
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var features = countries2.features;
d3.csv("//rawgit.com/jhjanicki/circles-to-bars/master/data/sum_by_country.csv", function(error, data) {
data.sort(function(a, b) {
return a.value - b.value;
});
var myfeatures = joinData(features, data, ['value']);
var worldMap = svg.append('g');
var world = worldMap.selectAll(".worldcountries")
.data(myfeatures)
.enter()
.append("path")
.attr("class", function(d) {
return "World " + d.properties.name + " worldcountries";
})
.attr("d", path)
.style("fill", "#ddd")
.style("stroke", "white")
.style("stroke-width", "1");
var radius = d3.scale.sqrt()
.domain([0, 1097805])
.range([3, 20]);
var newFeatures = [];
myfeatures.forEach(function(d) {
if (d.properties.hasOwnProperty("value")) {
console.log(d.properties.name);
newFeatures.push(d);
}
});
newFeatures.sort(function(a, b) {
return b.properties.value - a.properties.value;
});
var bubbles = svg.append("g").classed("bubbleG", "true");
bubbles.selectAll("rect")
.data(newFeatures)
.enter().append("rect")
.attr("class", "bubble")
.attr("transform", function(d) {
return "translate(" + path.centroid(d) + ")";
})
.attr("width", function(d) {
return radius(d.properties.value) * 2;
})
.attr("height", function(d){
return radius(d.properties.value) * 2;
})
.attr("rx", 20)
.attr("fill", "#2166ac")
.attr("stroke", "white")
.attr("id", function(d) {
return "circle " + d.properties.name;
});
$('#bubblebar').click(function() {
mapBarTransition(newFeatures, bubbles)
});
});
// button onclick
function mapBarTransition(data, bubbles) {
if (bubbleMapState == 'map') {
bubbleMapState == 'bar';
} else {
bubbleMapState == 'map';
}
var margin = {
top: 20,
right: 20,
bottom: 120,
left: 80
},
chartW = width - margin.left - margin.right,
chartH = height - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.domain(data.map(function(d) {
return d.properties.name;
}))
.rangeRoundBands([0, chartW], .4);
var y = d3.scale.linear()
.domain([0, 1097805])
.nice()
.range([chartH, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.ticks(8)
.orient("left");
var barW = width / data.length;
bubbles.append("g").classed("bubblebar-chart-group", true);
bubbles.append("g").classed("bubblebar-x-axis-group axis", true);
bubbles.append("g").classed("bubblebar-y-axis-group axis", true);
bubbles.transition().duration(1000).attr({
transform: "translate(" + margin.left + "," + margin.top + ")"
});
bubbles.select(".bubblebar-x-axis-group.axis")
.attr({
transform: "translate(0," + (chartH) + ")"
})
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
bubbles.select(".bubblebar-y-axis-group.axis")
.transition()
.call(yAxis);
barW = x.rangeBand();
var bars = d3.select(".bubbleG")
.selectAll(".bubble")
.data(data);
bars.enter().append("rect")
.classed("bubble", true)
.attr("x", function(d) {
return x(d.properties.name);
})
.attr("y", function(d) {
return y(d.properties.value);
})
.attr("width", barW)
.attr("height", function(d) {
return chartH - y(d.properties.value);
})
.attr("fill", "#2166ac");
bars.transition()
.duration(1000)
.attr("transform", function(d){
return "translate(" + x(d.properties.name) + "," + y(d.properties.value) + ")";
})
.attr("rx", 0)
.attr("width", barW)
.attr("height", function(d) {
return chartH - y(d.properties.value);
});
bars.exit().transition().style({
opacity: 0
}).remove();
}
function joinData(thisFeatures, thisData, DataArray) {
//loop through csv to assign each set of csv attribute values to geojson counties
for (var i = 0; i < thisData.length; i++) {
var csvCountry = thisData[i]; //the current county
var csvKey = csvCountry.Country; //the CSV primary key
//loop through geojson regions to find correct counties
for (var a = 0; a < thisFeatures.length; a++) {
var geojsonProps = thisFeatures[a].properties; //the current region geojson properties
var geojsonKey = geojsonProps.name; //the geojson primary key
//where primary keys match, transfer csv data to geojson properties object
if (geojsonKey == csvKey) {
//assign all attributes and values
DataArray.forEach(function(attr) {
var val = parseFloat(csvCountry[attr]); //get csv attribute value
geojsonProps[attr] = val; //assign attribute and value to geojson properties
});
};
};
};
return thisFeatures;
};
}
</script>
</body>
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.
I am begginer to d3.js and getting errors, I customized the example for my needs but gettings these in the console. Please help. Thank you in Advance.
Error: Invalid value for <path> attribute d="M-1.8369701987210297e-14,-100A100,100 0 1,1 NaN,NaNLNaN,NaNA60,60 0 1,0 -1.1021821192326178e-14,-60Z"a # d3.v3.min.js:1
d3.v3.min.js:1 Error: Invalid value for <path> attribute d="MNaN,NaNA100,100 0 1,1 NaN,NaNLNaN,NaNA60,60 0 1,0 NaN,NaNZ"
var getData = function () {
var size = 3;
var data =[];
var text = "";
data=[
{
label:"Saved",
value:200,
},{
label:"Ordered",
value:1255,
},{
label:"Shipped",
value:760,
},{
label:"Backordered",
value:150,
},
{
label:"Cancelled",
value:250,
},
];
d3.select("#data").html(text);
return data;
};
console.log(getData());
var chart = donut(250,200,16,40)
.$el(d3.select("#chart"))
.data(getData())
.render();
d3.select("#refresh").on("click", function () {
chart.data(getData()).render();
});
function donut(width,height,label_font_size,value_font_size) {
// Default settings
var $el = d3.select("body")
var data = {};
// var showTitle = true;
var width = width,
height = height,
radius = Math.min(width, height) / 2;
//var arc = d3.svg.arc().outerRadius(radius);
var arcOver = d3.svg.arc()
.innerRadius(radius + 20);
var currentVal;
var color = d3.scale.category20();
var pie = d3.layout.pie()
.sort(null)
.value(function (d) {
console.log(d);
return d.value.value;
});
var svg, g, arc;
var object = {};
// Method for render/refresh graph
object.render = function () {
if (!svg) {
arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2.5));
svg = $el.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
g = svg.selectAll(".arc")
.data(pie(d3.entries(data)))
.enter().append("g")
.attr("class", "arc");
g.append("path")
// Attach current value to g so that we can use it for animation
.each(function (d) {
//this._current = d;
})
.attr("d", arc)
.style("fill", function (d,i) {
return color(i);
});
/*g.append("text")
.attr("transform", function (d,i) {
return "translate(" + arc.centroid(d,i) + ")";
})
.attr("dy", ".35em")
.style("text-anchor", "middle");
g.select("text").text(function (d) {
//return d.data.key;
});
*/
svg.append("text")
.datum(data)
.attr("x", 0)
.attr("y", 0)
.attr("class", "text-tooltip")
.style("text-anchor", "middle")
.attr("font-weight", "bold")
.style("font-size", radius / 2.5 + "px");
g.on("mouseover", function (obj) {
var tooltipText=svg.select("text.text-tooltip");
tooltipText.attr("fill", function (d,i) {
return color(i);
});
tooltipText.append("tspan")
.attr("dy", -15)
.attr("x",0)
.attr("class", "text-tooltip-label")
.style("font-size", label_font_size + "px")
.text(function(d) {return d[obj.data.key].label;});
tooltipText.append("tspan")
.attr("dy", ".9em") // offest by 1.2 em
.attr("x",0)
.attr("class", "text-tooltip-value")
.style("font-size", value_font_size + "px")
.text(function(d) {return d[obj.data.key].value;});
d3.select(this)
.attr("stroke","white")
.transition()
.duration(1000)
.attr("d", arcOver)
.attr("stroke-width",6);
});
g.on("mouseout", function (obj) {
svg.select("text.text-tooltip").text("");
d3.select(this).transition()
.attr("d", arc)
.attr("stroke","none");
});
} else {
g.data(pie(d3.entries(data))).exit().remove();
g.select("path")
.transition().duration(200)
.attrTween("d", function (a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function (t) {
return arc(i(t));
};
});
g.select("text")
.attr("transform", function (d,i) {
return "translate(" + arc.centroid(d,i) + ")";
});
svg.select("text.text-tooltip").datum(data);
}
return object;
};
// Getter and setter methods
object.data = function (value) {
if (!arguments.length) return data;
data = value;
return object;
};
object.$el = function (value) {
if (!arguments.length) return $el;
$el = value;
return object;
};
object.width = function (value) {
if (!arguments.length) return width;
width = value;
radius = Math.min(width, height) / 2;
return object;
};
object.height = function (value) {
if (!arguments.length) return height;
height = value;
radius = Math.min(width, height) / 2;
return object;
};
return object;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>
I'm trying to make a pie chart using d3. To do this I am send my data in a JSON format to my view and then I'd like to try and total up three of the parameters and then use these in the pie chart. So far I have managed to get the data to the view but now I need to use a foreach to total up the parameters. I'm only working on one at the moment.
Script:
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function (d) { return d.Query; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = #Html.Raw(#Model.output);
var QueryTotal = data.forEach(function(d) {
d.Query = +d.Query;
});
console.log(QueryTotal);
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function (d) { return color("Query"); });
g.append("text")
.attr("transform", function (d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function (d) { return "Query"; });
How do I use a for each to total up the values, I've given it an attempt which you can see above. It just returns undefined.
To sum the values, use reduce()
var QueryTotal = data.reduce(function(prev, d) {
return prev + d.Query;
}, 0);
Or, using your existing structure:
var QueryTotal = 0;
data.forEach(function(d) {
QueryTotal += d.Query;
});
The D3 way to do this is to use d3.sum():
var QueryTotal = d3.sum(data, function(d) { return d.Query; });
I try to modify this example. I would like to create two data arrays and merge them using special mergingAr() function instead of data.csv. But it does not work. There is one-colour chart without any data. I can`t find the problem place in the code. So, here it is:
var width = 250,
height = 250,
radius = 230;
var arr1 = [44, 64]; //age
var arr2 = [14106543, 8819342]; //population
function type(d) {
d[1] = +d[1];
return d;
}
function mergingAr(array1, array2)
{
var i, out = [];
for(i=0;i<array1.length;i++)
{
out.push([array1[i],array2[i]]);
}
return out;
}
var data = mergingAr(arr1, arr2);
var color = d3.scale.ordinal()
.range(["#EB7221", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 180);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d[1]; });
var svg = d3.select("#pie").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d[0]); });
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d[0]; });
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
Thanks all for help!
Your data is there, but your color is wrong. Right now, you have this line setting path color:
.style("fill", function(d) { return color(d[0]); });
The problem is that your data is an object, not an array. (It's transformed by the pie function), so you need to reference the data attribute on the object, and then get the zero index of that array, like so:
.style("fill", function(d) { return color(d.data[0]); });