Unable to get stacks in d3 bar chart - javascript

I would like to know what i am doing wrong i think its in the axis as the stacked data as well as well as the rect elements are showing. Been stuck now for 2 hours.
var margin = {top: 10, right: 30, bottom: 20, left: 50},
width = 760 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
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 + ")");
innerheight=height + margin.top + margin.bottom
d3.csv("data.csv", function (error, data) {
if (error) {
throw error;
}
// var subgroups = data.columns.slice(1);
// console.log(subgroups);
var subgroups = d3.map(data, function(d){ return(d.Segment)}).keys();
var groups = d3.map(data, function(d){ return(d.Category)}).keys();
console.log(groups);
// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.2])
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSizeOuter(0));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.Sales; })])
.range([ height , 0 ]);
console.log(y.domain())
console.log(y.range())
svg.append("g")
.call(d3.axisLeft(y));
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#e41a1c','#377eb8','#4daf4a']);
ymax= d3.max(data, function(d) { return d.Sales; });
console.log(subgroups);
var stackedData = d3.stack().keys(subgroups);
stackedData = stackedData(data)
console.log(stackedData);
svg.append("g")
.selectAll("g")
// Enter in the stack data = loop key per key = group per group
.data(stackedData)
.enter().append("g")
.attr("fill", function (d) { return (color(d.key)); })
.selectAll("rect")
// enter a second time = loop subgroup per subgroup to add all rectangles
.data(function (d) { return d; })
.enter().append("rect")
.attr("x", function (d) { return x(d.data.Category); })
.attr("y", function (d) { return y(d.data.Sales); })
.attr("height", function (d) { return (height - y(d.data.Sales)) ; })
.attr("width", x.bandwidth())
});
csv is in this format
Row ID,Segment,Category,Sales,Total
1,Consumer,Accessories,84754.742,1007859.426
2,Consumer,Appliances,42852.68,1007859.426
31,Corporate,Phones,89019.204,588163.8014
34,Corporate,Tables,57226.0385,588163.8014
37,Home Office,Art,4799.502,373365.8573

Related

group Barchart gives an errror in d3

This is my expected result
Please Click to see Image
This is the data I am using: -
year,co2,ghg
2000,15.34,34.86
2001,15.54,34.86
2002,16.53,34.06
2003,17.03,29.74
2004,17.48,31.97
2005,16.98,29.66
2006,17.62,31.52
2007,19.82,30.91
2008,17.24,29.93
2009,17.66,29.14
2010,17.31,27.13
2011,17.43,28.61
2012,17.91,28.08
2013,16.67,23.88
2014,16.8,24
2015,16.6,23.67
2016,16.04,23.8
2017,15.78,25.34
2018,15.2,24.87
When I use it in HTML like this It works completely fine
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="main.css">
<title>Stacked Bar Graph</title>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.js"></script>
</head>
<body>
<script>
var margin = {top: 10, right: 30, bottom: 20, left: 50},
width = 1000 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
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 + ")");
d3.csv("data.csv", function(data) {
var subgroups = data.columns.slice(1);
var groups = d3.map(data, function(d){return(d.year)}).keys()
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.2])
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(5));
var y = d3.scaleLinear()
.domain([0, 40])
.range([ height, 0 ]);
svg.append("g")
.call(d3.axisLeft(y).ticks(8));
var xSubgroup = d3.scaleBand()
.domain(subgroups)
.range([0, x.bandwidth()])
.padding([0.05])
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#e41a1c','#377eb8','#4daf4a'])
svg.append("g")
.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d) { return "translate(" + x(d.year) + ",0)"; })
.selectAll("rect")
.data(function(d) { return subgroups.map(function(key) { return {key: key, value: d[key]}; }); })
.enter().append("rect")
.attr("x", function(d) { return xSubgroup(d.key); })
.attr("y", function(d) { return y(d.value); })
.attr("width", xSubgroup.bandwidth())
.attr("height", function(d) { return height - y(d.value); })
.attr("fill", function(d) { return color(d.key); });
})
</script>
</body>
</html>
But when I use it in a separate Js file like this
function GroupBar() {
// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 20, left: 50},
width = 1000 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
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 + ")");
// Parse the Data
d3.csv("src/data/co2_vs_ghg.csv", function(data) {
// List of subgroups = header of the csv files = soil condition here
var subgroups = data.columns.slice(1);
// List of groups = species here = value of the first column called group -> I show them on the X axis
var groups = d3.map(data, function(d){return(d.year)}).keys()
// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.2])
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(5));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, 40])
.range([ height, 0 ]);
svg.append("g")
.call(d3.axisLeft(y).ticks(8));
// Another scale for subgroup position?
var xSubgroup = d3.scaleBand()
.domain(subgroups)
.range([0, x.bandwidth()])
.padding([0.05])
// color palette = one color per subgroup
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#e41a1c','#377eb8','#4daf4a'])
// Show the bars
svg.append("g")
.selectAll("g")
// Enter in data = loop group per group
.data(data)
.enter()
.append("g")
.attr("transform", function(d) { return "translate(" + x(d.year) + ",0)"; })
.selectAll("rect")
.data(function(d) { return subgroups.map(function(key) { return {key: key, value: d[key]}; }); })
.enter().append("rect")
.attr("x", function(d) { return xSubgroup(d.key); })
.attr("y", function(d) { return y(d.value); })
.attr("width", xSubgroup.bandwidth())
.attr("height", function(d) { return height - y(d.value); })
.attr("fill", function(d) { return color(d.key); });
});
}
window.addEventListener("load", GroupBar);
It gives me an error
shown here
I have tried some alternate methods online but none of them work I think I am missing a minute detail but cannot figure out what if anyone can double check this it would be great

How to combine two CSV files into the same graph with d3js

I have a csv file "data_good.csv" with the simple format : date,value ("date" here is just a number, not date format.)
I've just started using d3js and here is the code i'm using for the graph :
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = screen.width - 200,
height = 200;
// set the ranges
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
// append the svg object to the body of the page
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#body_d3_graph").append("svg").attr("class","my_svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// get the data
d3.csv("tmp/data_good.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.value = +d.value;
});
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
// append the rectangles for the bar chart
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.style("fill", "green")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
// add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
});
It's working as expected with several green bars.
But now i have another csv file ("tmp/data_bad.csv") and i would like to have it as a red bar on top of the green one. According to their key "date". (There is no date without value : data_good.csv and data_bad.csv have the same number of lines.)
I think that you should separate logic which draws chart and logic which loads a file.
Also you have to group bars and separate drawing axes from bars.
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = screen.width - 200,
height = 200;
// set the ranges
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
// append the svg object to the body of the page
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#body_d3_graph").append("svg").attr("class","my_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 drawAxes = function(data) {
// add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
}
var drawChart = function(data) {
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
// append the rectangles for the bar chart
svg
.append('g')
.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.style("fill", "green")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
}
// get the data
d3.csv("tmp/data_good.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.value = +d.value;
});
drawChart(data);
});
Then if you want to preserve domain scaling to be defined only by "good data" you can abstract it too and use only in "good data reader".
Remember to draw axes when changing scales.
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = screen.width - 200,
height = 200;
// set the ranges
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
// append the svg object to the body of the page
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#body_d3_graph").append("svg").attr("class","my_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 drawAxes = function(data) {
// add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
}
var setDomains = function(data) {
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
drawAxes();
}
var drawChart = function(data) {
// append the rectangles for the bar chart
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.style("fill", "green")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
// add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
}
// get the data
d3.csv("tmp/data_good.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.value = +d.value;
});
setDomains(data);
drawChart(data);
});
d3.csv("tmp/data_bad.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.value = +d.value;
});
drawChart(data);
});

wrong date printing on x axis of line graph in d3 with extra tick

i am using D3 to draw line graph in JavaScript. Line of Line graph is drawn right but date on x axis is not correct and it is also showing one extra tick on x axis. I had also tried changing tick format but i failed. I don't know where i am doing wrong. please help. here is my code
var margin = {top: 50, right: 50, bottom: 50, left: 50}
, width = window.innerWidth - margin.left - margin.right // Use the window's width
, height = window.innerHeight - margin.top - margin.bottom; // Use the window's height
// The number of datapoints
var n = 4;
var xScale = d3.scaleLinear()
.domain([0, n-1]) // input
.range([0, width]); // output
var parseTime = d3.timeParse("%d-%b-%y");
// 6. Y scale will use the randomly generate number
var yScale = d3.scaleLinear()
.domain([0, 100]) // input
.range([height, 0]); // output
d3.csv("Data_vis.csv", function(data){
//console.log(data);
var nov_11_percent= 22;
var oct_16_percent= 25;
var nov_13_percent= 24;
var oct_22_percent= 21;
var dataset2=[{"date":'2018-09-11', "value": nov_11_percent},
{"date":'2018-10-16', "value": oct_16_percent},
{"date":'2018-10-22', "value": oct_22_percent},
{"date":'2018-11-13', "value": nov_13_percent}];
dataset2.forEach(function(d) {
d.date = new Date(d.date);
});
var line = d3.line()
.x(function(d, i) {
//alert(parseTime(d.date));
return xScale(d.date);
})
.y(function(d,i ) {
return yScale(d.value);
})
.curve(d3.curveMonotoneX)
xScale.domain(d3.extent(dataset2, function(d) {
return d.date; }));
yScale.domain([0, d3.max(dataset2, function(d) {
return d.value;
})]);
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 + ")");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale)
.ticks(4)
.tickFormat(d3.timeFormat("%Y-%m-%d")));
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(yScale));
svg.append("path")
.datum(dataset2)
.attr("class", "line")
.attr("d", line);
svg.selectAll(".dot")
.data(dataset2)
.enter().append("circle") // Uses the enter().append() method
.attr("class", "dot") // Assign a class for styling
.attr("cx", function(d) { return xScale(d.date) })
.attr("cy", function(d) { return yScale(d.value) })
.attr("r", 10);
});
any help would be much appreciated. thank you
Use a point scale instead of a linear scale for x.
var xScale = d3
.scalePoint()
.range([0, width])
.domain(dataset2.map(i => i.date))
const margin = { top: 50, right: 50, bottom: 50, left: 50 }
const width = window.innerWidth - margin.left - margin.right // Use the window's width
const height = window.innerHeight - margin.top - margin.bottom // Use the window's height
const dataset2 = [{ date: "2018-09-11", value: 22 },{ date: "2018-10-16", value: 25 },{ date: "2018-10-22", value: 24 },{ date: "2018-11-13", value: 21 }]
dataset2.forEach(function(d) {
d.date = new Date(d.date)
})
// 6. Y scale will use the randomly generate number
const yScale = d3
.scaleLinear()
.domain([
0,
d3.max(dataset2, function(d) {
return d.value
})
]) // input
.range([height, 0]) // output
const xScale = d3
.scalePoint()
.range([0, width])
.domain(dataset2.map(d => d.date))
const line = d3
.line()
.x(function(d, i) {
return xScale(d.date)
})
.y(function(d, i) {
return yScale(d.value)
})
.curve(d3.curveMonotoneX)
const 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 + ")")
svg
.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(
d3
.axisBottom(xScale)
.tickFormat(d3.timeFormat("%m/%d"))
)
svg
.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(yScale))
svg
.append("path")
.datum(dataset2)
.attr("class", "line")
.attr("d", line)
.attr("fill", "none")
.attr("stroke", "black")
svg
.selectAll(".dot")
.data(dataset2)
.enter()
.append("circle") // Uses the enter().append() method
.attr("class", "dot") // Assign a class for styling
.attr("cx", function(d) {
return xScale(d.date)
})
.attr("cy", function(d) {
return yScale(d.value)
})
.attr("r", 10)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Codepen

cant figure out d3.js error

var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
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 temp = [ {"Gender":"Male","count":5}, {"Gender":"Female","count":2}];
var data=[]
data.push(temp);
x.domain(data.map(function(d) { return d.Gender; }));
y.domain([0, d3.max(data, function(d) { return d.count; })]);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(data) { return x(data.Gender); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(data.count); })
.attr("height", function(d) { return height - y(data.count); });
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));
<style> /* set the CSS */
.bar { fill: steelblue; }
</style>
<!DOCTYPE html>
<body><script src="//d3js.org/d3.v4.min.js"></script></body>
I want a graph to plot male and female count. count in y-axis and gender in x-axis
my d3.js index.html
where data_json is the this data
[ {"Gender":"Male","count":5}, {"Gender":"Female","count":2}];
im getting graph for only 1 set i.e {"Gender":"Male","count":5} if i set data_json to the same else only axis is displayed.
but not together in same graph. Im new to d3.js and unable to figure out the solution. please help.
Your error is stems from this:
var temp = [ {"Gender":"Male","count":5}, {"Gender":"Female","count":2}];
var data=[]
data.push(temp);
The d3 .data method takes an array. Combined with an enter selection, one element can be appended per item in the array. temp is already an array, by pushing it to data you are making an array like the follows:
[[ {"Gender":"Male","count":5}, {"Gender":"Female","count":2}]]
This array has only one item, a sub-array. The sub-array is really what you want though. This is also creates problems when using the scales:
x.domain(data.map(function(d) { return d.Gender; }));
As each datum (and there is only one) comprises of an array, d.Gender will be undefined, d[1] will be defined.
Instead, use your temp array as your dataset without pushing it into a new array. Then modify the y, x, and height values of each rect to access d.count or d.Gender rather than data.Gender or data.count (as data.count is undefined, and also not datum specific, while d.count is the count associated with the datum bound to each rect).
Take a look at the snippet below which makes these changes:
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 500 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom;
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
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 data = [ {"Gender":"Male","count":5}, {"Gender":"Female","count":2}];
x.domain(data.map(function(d) { return d.Gender; }));
y.domain([0, d3.max(data, function(d) { return d.count; })]);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(data) { return x(data.Gender); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.count); })
.attr("height", function(d) { return height - y(d.count); });
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));
<style> /* set the CSS */
.bar { fill: steelblue; }
</style>
<!DOCTYPE html>
<body><script src="//d3js.org/d3.v4.min.js"></script></body>

Not able to plot rectangles using onclick function on a stack of each bar in stacked bar chart in d3

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");
});

Categories