Related
I'm building three line graphs in d3.js and I would like that when the viewer hovers over a section of the line graph, they are able to see the country, date and incidents. Currently all that is being returned is an undefined. any help would be immensely appreciated.
Here is my html:
<div id="callOut">
<div id="divCountry"></div>
<div id="divDate"></div>
<div id="divIncidents"></div>
</div>
Here are my helper functions:
function circleHover(chosen) {
if (modus == "incidents") {
d3.select("#callOut")
.style("top", "570px")
.style("left", "30px");
d3.select("#divCountry").html('Country: ' + chosen.country);
d3.select("#divDate").html('Date: ' + chosen.date);
d3.select("#divIncidents").html('Incidents: ' + chosen.incidents);
d3.select("#callOut")
.style("visibility","visible");
}
};
function showOne(d) {
var margin = {top: 80, right: 80, bottom: 80, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("#svg").append("svg")
.attr("width", width)
.attr("height", height);
var incidentsData = svg.append("g");
incidentsData.selectAll(".incidentsData")
.data(incidentData)
.enter()
.append('incidentsData')
.attr('class', 'incidentsData');
var chosen = d;
var setOpacity = 0;
if (modus == "incidents") {
circleHover(chosen);
setOpacity = 0.1;
incidentsData.selectAll(".incidentsData")
.filter(function (d) { return eval("d.country") !=
eval("chosen.country");})
.style("fill-opacity", setOpacity);
}
}
};
Here is a snapshot of my incidentsData:
var incidentData =
[
{
"country": "Israel",
"date": 1971,
"incidents": 1,
"": ""
},
{
"country": "Israel",
"date": 1972,
"incidents": 15,
"": ""
},
Here is my totalIncidentsLineGraph:
function totalIncidentsLineGraph() {
modus = "incidents";
var margin = {top: 80, right: 80, bottom: 80, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("#svg").append("svg")
.attr("width", width)
.attr("height", height);
var incidentsData = svg.append("g");
incidentsData.selectAll(".incidentsData")
.data(incidentData)
.enter()
.append('incidentsData')
.attr('class', 'incidentsData')
.attr('id', function(d) { return d.country, d.date,
d.incidents});
var parse = d3.time.format("%Y").parse;
var x = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
xAxis = d3.svg.axis().scale(x).tickSize(-height).tickSubdivide(true),
yAxis = d3.svg.axis().scale(y).ticks(4).orient("right");
var area = d3.svg.area()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.incidents); });
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.incidents); });
function type(d) {
d.country = d.country;
d.date = parse(d.date);
d.incidents = +d.incidents
return d;
};
var data = d3.csv("static/data/israel/incidents_linechart.csv", type,
function(error, data) {
console.log(data);
var israel = data.filter(function(d) {
return d.country == "Israel";
});
var unitedStates = data.filter(function(d) {
return d.country == "United States";
});
var iran = data.filter(function(d) {
return d.country == "Iran";
});
x.domain([unitedStates[0].date, unitedStates[unitedStates.length -
1].date]);
y.domain([0, d3.max(egypt, function(d) { return d.incidents;
})]).nice();
var svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top +
")")
svg.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ",0)")
.call(yAxis);
svg.append("text")
.attr("id", "titleLine")
.attr("y", -50)
.attr("x", 250)
.attr("dy", ".35em")
.style("font-size", "12px")
.text("Total Incidents Amongst Countries: 1970 - 2017");
var colors = d3.scale.category10();
svg.selectAll('.line')
.data([israel, unitedStates, iran, saudiArabia, turkey, egypt, syria,
lebanon, jordan, palestine]) /// can add however many i want here
.enter()
.append('path')
.attr('class', 'line')
.style('stroke', function(d) {
return colors(Math.random() * 50);
})
.attr('clip-path', 'url(#clip)')
.attr('d', function(d) {
return line(d);
})
.on("mouseover", showOne)
.on("mouseout", showAll);
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>
In a web application I was supposed to create a vertically grouped bar chart using d3.js using json data. Previously I create a horizontal grouped bar using the following code. Can anyone help me out? Thanks in advance.
var data = {
labels: [
'resilience', 'maintainability', 'accessibility',
'uptime', 'functionality', 'impact'
],
series: [
{
label: '2012',
values: [4, 8, 15, 16, 23, 42]
},
{
label: '2013',
values: [12, 43, 22, 11, 73, 25]
},
{
label: '2014',
values: [31, 28, 14, 8, 15, 21]
},]
};
var chartWidth = 300,
barHeight = 20,
groupHeight = barHeight * data.series.length,
gapBetweenGroups = 10,
spaceForLabels = 150,
spaceForLegend = 150;
// Zip the series data together (first values, second values, etc.)
var zippedData = [];
for (var i=0; i<data.labels.length; i++) {
for (var j=0; j<data.series.length; j++) {
zippedData.push(data.series[j].values[i]);
}
}
// Color scale
var color = d3.scale.category20();
var chartHeight = barHeight * zippedData.length + gapBetweenGroups * data.labels.length;
var x = d3.scale.linear()
.domain([0, d3.max(zippedData)])
.range([0, chartWidth]);
var y = d3.scale.linear()
.range([chartHeight + gapBetweenGroups, 0]);
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat('')
.tickSize(0)
.orient("left");
// Specify the chart area and dimensions
var chart = d3.select(".chart")
.attr("width", spaceForLabels + chartWidth + spaceForLegend)
.attr("height", chartHeight);
// Create bars
var bar = chart.selectAll("g")
.data(zippedData)
.enter().append("g")
.attr("transform", function(d, i) {
return "translate(" + spaceForLabels + "," + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i/data.series.length))) + ")";
});
// Create rectangles of the correct width
bar.append("rect")
.attr("fill", function(d,i) { return color(i % data.series.length); })
.attr("class", "bar")
.attr("width", x)
.attr("height", barHeight - 1);
// Add text label in bar
bar.append("text")
.attr("x", function(d) { return x(d) - 3; })
.attr("y", barHeight / 2)
.attr("fill", "red")
.attr("dy", ".35em")
.text(function(d) { return d; });
// Draw labels
bar.append("text")
.attr("class", "label")
.attr("x", function(d) { return - 10; })
.attr("y", groupHeight / 2)
.attr("dy", ".35em")
.text(function(d,i) {
if (i % data.series.length === 0)
return data.labels[Math.floor(i/data.series.length)];
else
return ""});
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + spaceForLabels + ", " + -gapBetweenGroups/2 + ")")
.call(yAxis);
// Draw legend
var legendRectSize = 18,
legendSpacing = 4;
var legend = chart.selectAll('.legend')
.data(data.series)
.enter()
.append('g')
.attr('transform', function (d, i) {
var height = legendRectSize + legendSpacing;
var offset = -gapBetweenGroups/2;
var horz = spaceForLabels + chartWidth + 40 - legendRectSize;
var vert = i * height - offset;
return 'translate(' + horz + ',' + vert + ')';
});
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', function (d, i) { return color(i); })
.style('stroke', function (d, i) { return color(i); });
legend.append('text')
.attr('class', 'legend')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function (d) { return d.label; });
After continuous digging I found the correct way of doing this. Thanks to Mike Bostock for the example he provided in here. In here you can also find out the elaborate discussion of that example. Thanks for your support :)
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
//console.log(margin.left);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
/*Our json object is [{letter: "A", frequency: .08167,depth:.32},{letter: "B", frequency: .01492,depth:.69}]
To use csv file you just need to follow the link I provided
*/
var data = [
{letter: "A", frequency: .08167,depth:.32},
{letter: "B", frequency: .01492,depth:.69}
];
var groupNames=d3.keys(data[0]).filter(function(key){return key!="letter";})
data.forEach(function(d){
d.groups=groupNames.map(function(name){return {name:name,value:+d[name]};})
});
x0.domain(data.map(function(d){return d.letter;}));
x1.domain(groupNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0,d3.max(data,function(d){
return d3.max(d.groups,function(d){
return d.value;
});
})]);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Letter Fun");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x0(d.letter) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.groups; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
Please let me know if you have anything to know about the code.
I have a brush coordinated with a bar chart. When the brush is moved and resized the bar chart shows only the filtered bars. In the same page I have a pie chart that isn't coordinated with the bar chart and the brush, but I want it to be. I want that also the pie chart updates its content according to the filtered values. How can I do that?
This is my code, followed by the plnkr link where you can see what I've done so far:
<script type="text/javascript">
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40,
mid: 20
},
w = 750 - margin.left - margin.right,
h = 300 - margin.top - margin.bottom;
var barPadding = 1;
var padding = 20;
var miniHeight = 60;
var selected;
var svg = d3.select(".outer-wrapper .chart").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.mid + miniHeight + margin.bottom)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var barsGroup = svg.append('g')
.attr("class","barsGroup");
var miniGroup = svg.append('g')
.attr("class","miniGroup")
.attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");
var brushGroup = svg.append('g')
.attr("class","brushGroup")
.attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");
var w2 = 400;
var h2 = 400;
var outerRadius = w2 / 2;
var innerRadius = w2 / 3;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.values; });
var color = d3.scale.category20c();
var svg2 = d3.select("body")
.append("svg")
.attr("width", w2)
.attr("height", h2);
d3.csv("data.csv", function(data) {
var dataset = d3.nest()
.key(function(d) {
return d.Year;
})
.sortKeys(d3.ascending)
.rollup(function(values) {
return values.length;
})
.entries(data)
.filter(function(d) {
return d.key != "UNK" && d.key != "VAR" && d.key != 199 && d.key != 211 && d.key != 2017;
});
//SCALES
var xScale = d3.scale.ordinal()
.domain(dataset.map(function(d) {
return d.key
}))
.rangeRoundBands([0, w], 0.05);
var xScaleBrush = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d.values;
})])
.range([h, 0]);
//AXIS
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickValues([1900,1920,1930,1940,1950,1960,1970,1980,1990,2000, 2010]);
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(6)
.orient("left");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class","x2 axis")
.attr("transform", "translate(" + 0 + "," + (margin.top + h + margin.mid + miniHeight) + ")" )
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
.append("g")
.attr("class", "axisLabel")
.append("text")
.attr("transform", "translate(" + -(margin.left * 0.8) + "," + (h/2) + "), rotate(-90)")
.style("text-anchor", "middle")
.text("Score");
var brush = d3.svg.brush()
.x(xScaleBrush)
.extent([0, w])
.on("brush", display);
brushGroup.append("g")
.attr("class", "brush")
.call(brush)
.selectAll("rect")
.attr("opacity", 0.5)
.attr("height", miniHeight);
function display() {
selected = xScaleBrush.domain()
.filter(function(d){
return (brush.extent()[0] <= xScaleBrush(d)) && (xScaleBrush(d) <= brush.extent()[1]);
});
var start;
var end;
/* Keep a minimum amount of bars on there to avoid any jank */
if (selected.length > 2) {
start = selected[0];
end = selected[selected.length - 1] + 1;
} else {
start = 0;
end = dataset.length;
}
var updatedData = dataset.slice(start, end);
updateBars(updatedData);
}
function update(grp, data, main) {
grp.selectAll("rect").data(data, function(d) {
return d.key;
})
.attr("x", function(d) {
return xScale(d.key);
})
.attr("y", function(d) {
return main ? yScale(d.values) : 0;
})
.attr("width", function (d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return main ? h - yScale(d.values) : miniHeight;
});
}
function enter(grp, data, main) {
grp.selectAll("rect").data(data, function(d) {
return d.key;
})
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(d.key);
})
.attr("y", function(d) {
return main ? yScale( d.values) : 0;
})
.attr("width", function(d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return main ? h - yScale(d.values) : miniHeight;
})
.attr("fill", function(d) {
var color = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d.values;
})])
.range([200, 244]);
var deg = color(d.values);
return "hsl(" + deg + ", 100%, 50%)";
})
.on("mouseover", function(d) {
if(main){
d3.select(this)
.attr("fill", "orange");
var xPosition = parseFloat(d3.select(this).attr("x"));
var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + 100;
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.style("z-index", "10")
.select("#value")
.text(d.values);
d3.select("#tooltip")
.select("#key")
.text("Film del " + d.key + " rilasciati su DVD");
d3.select("#tooltip").classed("hidden", false);
}
})
.on("mouseout", function(d) {
d3.select(this)
.transition()
.duration(250)
.attr("fill", function(d) {
var color = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d.values;
})])
.range([200, 244]);
var deg = color(d.values);
return "hsl(" + deg + ", 100%, 50%)";
});
d3.select("#tooltip").classed("hidden", true);
});
}
function exit(grp, data) {
grp.selectAll("rect").data(data, function(d) {
return d.key;
}).exit()
.remove();
}
function updateBars(data) {
xScale.domain(data.map(function(d) {
return d.key
}));
yScale.domain([0, d3.max(data, function(d) {
return d.values;
})]);
/* Update */
update(barsGroup, data, true);
/* Enter… */
enter(barsGroup, data, true);
/* Exit */
exit(barsGroup, data);
svg.select(".outer-wrapper .chart .y")
.transition()
.duration(10)
.call(yAxis);
svg.select(".outer-wrapper .chart .x")
.transition()
.duration(50)
.call(xAxis);
}
enter(miniGroup, dataset, false);
updateBars(dataset);
var dataset2 = d3.nest()
.key(function(d) { return d.Genre; })
.sortKeys(d3.ascending)
.rollup(function(values) { return values.length; })
.entries(data);
var text = svg2.append("text")
.attr("dx", 200)
.attr("dy", 200)
.attr("font-size", 30)
.style("text-anchor", "middle")
.attr("fill", "#36454f");
var text2 = svg2.append("text")
.attr("dx", 200)
.attr("dy", 230)
.attr("font-size", 20)
.style("text-anchor", "middle")
.attr("fill", "#36454f");
var text3 = svg2.append("text")
.attr("dx", 200)
.attr("dy", 260)
.attr("font-size", 20)
.style("text-anchor", "middle")
.attr("fill", "#36454f");
//Set up groups
var arcs = svg2.selectAll("g.arc")
.data(pie(dataset2))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
.on("mouseover", function(d) {
var total = data.length;
var percent = Math.round(1000 * d.value / total) / 10;
text.text(d.data.key).attr("class", "inner-circle");
text2.text(d.value + " DVD");
text3.text(percent +"%");
})
.on("mouseout", function(d) {
text.text(function(d) { return ""; });
text2.text(function(d) { return ""; });
text3.text(function(d) { return ""; });
});
//Draw arc paths
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
});
</script>
http://plnkr.co/edit/cwNl6zUSOM4yPmUtSRr4?p=preview
You can do that by transforming the part where you build the pieChart into a function that receives the new data.
The only adjustment is that the first thing I'm doing is removing the previous pie chart, to draw it again with the new data:
function updatePie(data){
svg2.selectAll("g.arc").remove();
Here is the complete code:
<script type="text/javascript">
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40,
mid: 20
},
w = 750 - margin.left - margin.right,
h = 300 - margin.top - margin.bottom;
var barPadding = 1;
var padding = 20;
var miniHeight = 60;
var selected;
var svg = d3.select(".outer-wrapper .chart").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.mid + miniHeight + margin.bottom)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var barsGroup = svg.append('g')
.attr("class","barsGroup");
var miniGroup = svg.append('g')
.attr("class","miniGroup")
.attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");
var brushGroup = svg.append('g')
.attr("class","brushGroup")
.attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");
var w2 = 400;
var h2 = 400;
var outerRadius = w2 / 2;
var innerRadius = w2 / 3;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.values; });
var color = d3.scale.category20c();
var svg2 = d3.select("body")
.append("svg")
.attr("width", w2)
.attr("height", h2);
d3.csv("data.csv", function(data) {
var dataset = d3.nest()
.key(function(d) {
return d.Year;
})
.sortKeys(d3.ascending)
.rollup(function(values) {
return values.length;
})
.entries(data)
.filter(function(d) {
return d.key != "UNK" && d.key != "VAR" && d.key != 199 && d.key != 211 && d.key != 2017;
});
//SCALES
var xScale = d3.scale.ordinal()
.domain(dataset.map(function(d) {
return d.key
}))
.rangeRoundBands([0, w], 0.05);
var xScaleBrush = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d.values;
})])
.range([h, 0]);
//AXIS
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickValues([1900,1920,1930,1940,1950,1960,1970,1980,1990,2000, 2010,2020,2030,2040,2050,2060]);
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(6)
.orient("left");
//Appendi asse x
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
//Asse x per brush
svg.append("g")
.attr("class","x2 axis")
.attr("transform", "translate(" + 0 + "," + (margin.top + h + margin.mid + miniHeight) + ")" )
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
.append("g")
.attr("class", "axisLabel")
.append("text")
.attr("transform", "translate(" + -(margin.left * 0.8) + "," + (h/2) + "), rotate(-90)")
.style("text-anchor", "middle")
.text("Score");
var brush = d3.svg.brush()
.x(xScaleBrush)
.extent([0, w])
.on("brush", display);
brushGroup.append("g")
.attr("class", "brush")
.call(brush)
.selectAll("rect")
.attr("opacity", 0.5)
.attr("height", miniHeight);
function display() {
selected = xScaleBrush.domain()
.filter(function(d){
return (brush.extent()[0] <= xScaleBrush(d)) && (xScaleBrush(d) <= brush.extent()[1]);
});
var start;
var end;
/* Keep a minimum amount of bars on there to avoid any jank */
if (selected.length > 2) {
start = selected[0];
end = selected[selected.length - 1] + 1;
} else {
start = 0;
end = dataset.length;
}
var updatedData = dataset.slice(start, end);
updateBars(updatedData);
updatePie(updatedData);
}
function update(grp, data, main) {
grp.selectAll("rect").data(data, function(d) {
return d.key;
})
.attr("x", function(d) {
return xScale(d.key);
})
.attr("y", function(d) {
return main ? yScale(d.values) : 0;
})
.attr("width", function (d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return main ? h - yScale(d.values) : miniHeight;
});
}
function enter(grp, data, main) {
grp.selectAll("rect").data(data, function(d) {
return d.key;
})
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(d.key);
})
.attr("y", function(d) {
return main ? yScale( d.values) : 0;
})
.attr("width", function(d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return main ? h - yScale(d.values) : miniHeight;
})
.attr("fill", function(d) {
var color = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d.values;
})])
.range([200, 244]);
var deg = color(d.values);
return "hsl(" + deg + ", 100%, 50%)";
})
.on("mouseover", function(d) {
if(main){
d3.select(this)
.attr("fill", "orange");
var xPosition = parseFloat(d3.select(this).attr("x"));
var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + 100;
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.style("z-index", "10")
.select("#value")
.text(d.values);
d3.select("#tooltip")
.select("#key")
.text("Film del " + d.key + " rilasciati su DVD");
d3.select("#tooltip").classed("hidden", false);
}
})
.on("mouseout", function(d) {
d3.select(this)
.transition()
.duration(250)
.attr("fill", function(d) {
var color = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d.values;
})])
.range([200, 244]);
var deg = color(d.values);
return "hsl(" + deg + ", 100%, 50%)";
});
d3.select("#tooltip").classed("hidden", true);
});
}
function exit(grp, data) {
grp.selectAll("rect").data(data, function(d) {
return d.key;
}).exit()
.remove();
}
function updateBars(data) {
xScale.domain(data.map(function(d) {
return d.key
}));
yScale.domain([0, d3.max(data, function(d) {
return d.values;
})]);
/* Update */
update(barsGroup, data, true);
/* Enter… */
enter(barsGroup, data, true);
/* Exit */
exit(barsGroup, data);
svg.select(".outer-wrapper .chart .y")
.transition()
.duration(10)
.call(yAxis);
svg.select(".outer-wrapper .chart .x")
.transition()
.duration(50)
.call(xAxis);
}
enter(miniGroup, dataset, false);
updateBars(dataset);
var dataset2 = d3.nest()
.key(function(d) { return d.Genre; })
.sortKeys(d3.ascending)
.rollup(function(values) { return values.length; })
.entries(data);
var text = svg2.append("text")
.attr("dx", 200)
.attr("dy", 200)
.attr("font-size", 30)
.style("text-anchor", "middle")
.attr("fill", "#36454f");
var text2 = svg2.append("text")
.attr("dx", 200)
.attr("dy", 230)
.attr("font-size", 20)
.style("text-anchor", "middle")
.attr("fill", "#36454f");
var text3 = svg2.append("text")
.attr("dx", 200)
.attr("dy", 260)
.attr("font-size", 20)
.style("text-anchor", "middle")
.attr("fill", "#36454f");
function updatePie(data){
svg2.selectAll("g.arc").remove();
var arcs = svg2.selectAll("g.arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
.on("mouseover", function(d) {
var total = data.length;
var percent = Math.round(1000 * d.value / total) / 10;
text.text(d.data.key).attr("class", "inner-circle");
text2.text(d.value + " DVD");
text3.text(percent +"%");
})
.on("mouseout", function(d) {
text.text(function(d) { return ""; });
text2.text(function(d) { return ""; });
text3.text(function(d) { return ""; });
});
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
}
updatePie(dataset2);
});
I am creating a stacked bar chart where stacks of each bar represents the status -"open","wip" respectively.what my requirement is that,triggering click event on each stacks of bar,3 rectangle should appear which represents "sev-high","sev-low","sev-medium" with respective count ...it means clicking on each stacks which represents "status",the total count for that status will get splited up into 3 bars showing "sev-high","sev-low","sev-medium" for that particular status..but here i am not able to plot the rectangle after clicking on stacks...please go through my code and suggest me ...
here is my code...
var data=[{"comp_catgry":"A","age":"0-5","status":"open","sev":"high","cnt":"40"}
,{"comp_catgry":"A","age":"0-5","status":"open","sev":"low","cnt":"10"}
,{"comp_catgry":"A","age":"0-5","status":"open","sev":"medium","cnt":"20"}
,{"comp_catgry":"A","age":"0-5","status":"wip","sev":"high","cnt":"40"}
,{"comp_catgry":"A","age":"0-5","status":"wip","sev":"low","cnt":"40"}
,{"comp_catgry":"A","age":"0-5","status":"wip","sev":"medium","cnt":"20"}
,{"comp_catgry":"A","age":"6-10","status":"open","sev":"high","cnt":"40"}
,{"comp_catgry":"A","age":"6-10","status":"open","sev":"low","cnt":"40"}
,{"comp_catgry":"A","age":"6-10","status":"open","sev":"medium","cnt":"40"}
,{"comp_catgry":"A","age":"6-10","status":"wip","sev":"high","cnt":"30"}
,{"comp_catgry":"A","age":"6-10","status":"wip","sev":"low","cnt":"40"}
,{"comp_catgry":"A","age":"6-10","status":"wip","sev":"medium","cnt":"10"}
,{"comp_catgry":"B","age":"0-5","status":"open","sev":"high","cnt":"40"}
,{"comp_catgry":"B","age":"0-5","status":"open","sev":"low","cnt":"50"}
,{"comp_catgry":"B","age":"0-5","status":"open","sev":"medium","cnt":"40"}
,{"comp_catgry":"B","age":"0-5","status":"wip","sev":"high","cnt":"40"}
,{"comp_catgry":"B","age":"0-5","status":"wip","sev":"low","cnt":"40"}
,{"comp_catgry":"B","age":"0-5","status":"wip","sev":"medium","cnt":"30"}
,{"comp_catgry":"B","age":"6-10","status":"open","sev":"high","cnt":"40"}
,{"comp_catgry":"B","age":"6-10","status":"open","sev":"low","cnt":"40"}
,{"comp_catgry":"B","age":"6-10","status":"open","sev":"medium","cnt":"40"}
,{"comp_catgry":"B","age":"6-10","status":"wip","sev":"high","cnt":"20"}
,{"comp_catgry":"B","age":"6-10","status":"wip","sev":"low","cnt":"40"}
,{"comp_catgry":"B","age":"6-10","status":"wip","sev":"medium","cnt":"30"}
]
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 760 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y0 = d3.scale.ordinal()
.rangeRoundBands([height, 0], .2);
var y1 = d3.scale.linear();
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var nestedData = d3.nest()
.key(function(d) {return d.comp_catgry;})
.key(function(d) {return d.age;})
.key(function(d) {return d.status;})
.entries(data);
console.log(nestedData);
var maxTotal = 0;
nestedData.forEach(function(catGroup) {
catGroup.ctgry = catGroup.key;
catGroup.values.forEach(function(ageGroup){
ageGroup.age = ageGroup.key;
ageGroup.bars=[];
var total1=0;
ageGroup.values.forEach(function(stsGroup){
stsGroup.sts=stsGroup.key;
var total = 0;
stsGroup.bars = [];
stsGroup.values.forEach(function(d){
stsGroup.bars.push(
{ctgry:catGroup.ctgry,
age:ageGroup.age,
status:d.status,
// type: "open",
sev:d.sev,
cnt1:d.cnt,
z0: total,
z1: (total = total + (+d.cnt) )
}
);
})
ageGroup.bars.push({
ctgry:catGroup.ctgry,
age:ageGroup.age,
status:stsGroup.key,
y0:total1,
y1:(total1 = total1 + total)
}
);
maxTotal = Math.max(maxTotal, total1);
});
});
});
x.domain( nestedData[0].values.map(function(d){return d.age;}) );
y0.domain(nestedData.map(function(d) { return d.key; }));
y1.domain([0, maxTotal]).range([y0.rangeBand(), 0]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var dateGroups = svg.selectAll("dateGroups")
.data(nestedData)
.enter()
.append("g")
.attr("class", "dateGroups")
.attr("transform", function(d) { return "translate(60," + y0(d.key) + ")"; });
dateGroups.append("text")
.attr("class", "group-label")
.attr("x", -76)
.attr("y", function(d) { return y0(d.values[0].value / 4); })
.attr("dy", ".35em")
.text(function(d) { return "Complaint Category " + d.key; })
var ageGroups = dateGroups.selectAll("ageGroups")
.data(function(d,i){console.log(nestedData[i].values); return nestedData[i].values;})
.enter()
.append("g")
.attr("class", "ageGroups")
var bars = ageGroups.selectAll("rect")
.data( function(d) {console.log(d.bars); return d.bars;})
.enter().append("rect")
.attr("id",function(d,i){return "Cust_"+i ;})
.attr("y", function(d){
return y1(d.y1);} )
.attr("height", function(d){return Math.abs( y1(d.y1) - y1(d.y0) ); } )
.attr("height", function(d) { return y0.rangeBand() - (Math.abs( y1(d.y1) - y1(d.y0) )); })
.attr("x", function(d,i){return x(d.age);})
.attr("width", x.rangeBand() )
.style("fill", function(d) { return color(d.status); })
/* .append("title")
.text(function(d) {
return ("Age Bucket-"+d.age + ", " +d.status +":" + d.count);
})*/
.on("click", function(d,i){
alert(1)
var bb = ageGroups.append("g").selectAll("rect").data( function(d) {console.log(d.values[i]); return d.values[i];})
.enter();
alert(2)
bb.append("rect")
.attr("id","rectId")
.attr("x",50)
.attr("Y",50)
.attr("height",function(d,i){ alert(3);console.log(d.bars[i].sev);return d.bars[i].sev;})
.attr("width",10)
.style("fill","red")
.style("visibility", "visible");
});