function renderNormalizedStackBarChart(inputData,dom_element_to_append_to) {
var mainMargin = {
top: 20,
right: 190,
bottom: 150,
left: 60
},
width = 900 - mainMargin.left - mainMargin.right,
height = 500 - mainMargin.top - mainMargin.bottom,
miniMargin = {
top: 50,
bottom: 150,
left: 40,
right: 190
},
miniHeight = 50;
var xscale = d3.time.scale()
.range([0, width]);
var miniXScale = d3.time.scale()
.range([0, width]);
var dateFormat = d3.time.format("%a %d");
var yScaleLeft = d3.scale.linear()
.rangeRound([height, 0]);
var yScaleRight = d3.scale.linear()
.rangeRound([height, 0]);
var miniyScaleLeft = d3.scale.linear()
.rangeRound([miniHeight, 0]);
var miniyScaleRight = d3.scale.linear()
.rangeRound([miniHeight, 0]);
var colors = d3.scale.ordinal()
.range(["#63c172", "#ee9952", "#46d6c4", "#fee851", "#98bc9a"]);
console.log(inputData);
var xaxis = d3.svg.axis()
.scale(xscale)
.orient("bottom")
.tickFormat(function(d) {
return (new Date(+d) + "").substring(3,21);
});
var miniXAxis = d3.svg.axis()
.scale(miniXScale)
.tickFormat(function(d) {
return (new Date(+d) + "").substring(0,16);
})
.orient("bottom");
var yAxisLeft = d3.svg.axis()
.scale(yScaleLeft)
.orient("left")
.tickFormat(d3.format(".0%"));
var yAxisRight = d3.svg.axis()
.scale(yScaleRight)
.orient("right")
.tickFormat(d3.format(".0%"));
var line = d3.svg.line()
.x(function(d, i) {
return xscale(d.response) ;
})
.y(function(d) {
return yScaleRight(d.value);
});
var miniLine = d3.svg.line()
.x(function(d, i) {
return miniXScale(d.response) + miniXScale.rangeBand()/2;
})
.y(function(d) {
return miniyScaleRight(d.value);
});
var svg = d3.select(dom_element_to_append_to).append("svg")
.attr("width", width + mainMargin.left + mainMargin.right )
.attr("height", height + mainMargin.top + mainMargin.bottom);
svg.append("g")
.attr("class", "y axisLeft")
.attr("transform", function() { return "translate(" + (mainMargin.left ) + "," + mainMargin.top + ")"; })
.call(yAxisLeft);
svg.append("g")
.attr("class", "y axisRight")
.attr("transform", function() { return "translate(" + (width + mainMargin.left ) + "," + mainMargin.top + ")"; })
.call(yAxisRight);
var main = svg.append("svg")
.attr("width", width + mainMargin.left )
.append("g")
.attr("transform", "translate(" + mainMargin.left + "," + mainMargin.top + ")");
var mini = svg.append("svg")
.attr("width", width + miniMargin.left + 15 )
.append("g")
.attr("transform", "translate(" + (miniMargin.left*1.5) + "," + (0) + ")");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
var date = (new Date(+d.CategoryNames) + "" ).substring(0,25);
return "
Date: " + date + "
" +
" " + d.response+ " (" + (d.yp1*100).toFixed(0) +"%): " + "" + d.y1 + " times
";
});
svg.call(tip);
var categories = d3.keys(inputData[0]).filter(function(key) { return key !== "CategoryNames"; });
var parsedata = categories.map(function(name) { return { "CategoryNames": name }; });
inputData.forEach(function(d) {
parsedata.forEach(function(pd) {
pd[d["CategoryNames"]] = d[pd["CategoryNames"]];
});
});
colors.domain(d3.keys(parsedata[0]).filter(function(key) { return key !== "CategoryNames" && key !== "Base"; }));
parsedata.forEach(function(pd) {
var y0 = 0;
pd.responses = colors.domain().map(function(response) {
var responseobj = {response: response, y0: y0, yp0: y0};
y0 += +pd[response];
responseobj.y1 = y0;
responseobj.yp1 = y0;
responseobj.CategoryNames = pd.CategoryNames;
return responseobj;
});
pd.responses.forEach(function(d) { d.yp0 /= y0; d.yp1 /= y0; });
pd.totalresponses = pd.responses[pd.responses.length - 1].y1;
});
xscale.domain(d3.extent(parsedata, function(d) { return +d.CategoryNames; }) );
//mainX1.domain(xscale.domain());
miniXScale.domain(xscale.domain());
yScaleRight.domain([0, d3.max(parsedata, function(d) { return d.totalresponses; })]);
yAxisRight.tickFormat(d3.format(".2s"));
var brush = d3.svg.brush()
.x(miniXScale)
.on("brush", brushed);
xaxis.ticks(parsedata.length);
main.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis)
.selectAll("text")
.attr("y", 5)
.attr("x", 7)
.attr("dy", ".35em")
.attr("transform", "rotate(65)")
.style("text-anchor", "start");
var category = main.selectAll(".category")
.data(parsedata)
.enter().append("g")
.attr("class", "category")
.attr("transform", function(d) { return "translate(" + xscale(+d.CategoryNames) + ",0)"; });
console.log(parsedata);
category.selectAll("rect")
.data(function(d) { return d.responses; })
.enter().append("rect")
.attr("width", width/(parsedata.length+10))
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
.attr("fill", function(d) { return colors(d.response); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
var convertedData = [];
parsedata.forEach(function(item) {
convertedData.push({response: item.CategoryNames, value: item.responses[0].y1})
});
main.append("path")
.data(convertedData)
.attr("class", "line")
.attr("d", line(convertedData))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
var miniCategory = mini.selectAll(".mini_category")
.data(parsedata)
.enter().append("g")
.attr("class", "mini_category")
.attr("transform", function(d) { return "translate(" + (miniXScale(d.CategoryNames) ) + "," + (height+miniMargin.top + 50) + ")"; });
miniCategory.selectAll("rect")
.data(function(d) { return d.responses; })
.enter().append("rect")
.attr("width", width/(parsedata.length+10))
.attr("y", function(d) { return miniyScaleLeft(d.yp1); })
.attr("height", function(d) { return miniyScaleLeft(d.yp0) - miniyScaleLeft(d.yp1) ; })
.style("fill", function(d) { return colors(d.response); });
mini.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", miniHeight + 15)
.attr("transform", "translate(" + 0 + "," + (height+miniMargin.top + 50) + ")");
var legend = svg.selectAll(".legend")
.data(colors.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(82," + (((height+miniMargin.top + 50)) + (i * 20)) + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", colors);
legend.append("text")
.attr("x", width + 10)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d) { return d; });
mini.append("g")
.attr("class", "x axis1")
.attr("transform", "translate(0," + (height+miniMargin.top + 50 + miniHeight) + ")")
.call(miniXAxis);
d3.selectAll("input").on("change", handleFormClick);
function handleFormClick() {
if (this.value === "bypercent") {
transitionPercent();
} else {
transitionCount();
}
}
function transitionPercent() {
yScaleLeft.domain([0, 1]);
miniyScaleLeft.domain([0, 1]);
var transMain = main.transition().duration(250);
var transMini = mini.transition().duration(250);
var categories = transMain.selectAll(".category");
categories.selectAll("rect")
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); });
var miniCategories = transMini.selectAll(".mini_category");
miniCategories.selectAll("rect")
.attr("y", function(d) { return miniyScaleLeft(d.yp1); })
.attr("height", function(d) { return miniyScaleLeft(d.yp0) - miniyScaleLeft(d.yp1); });
yAxisLeft.tickFormat(d3.format(".0%"));
main.selectAll(".y.axisLeft").call(yAxisLeft);
}
function transitionCount() {
yScaleLeft.domain([0, d3.max(parsedata, function(d) { return d.totalresponses; })]);
miniyScaleLeft.domain([0, d3.max(parsedata, function(d) { return d.totalresponses; })]);
var transoneMain = main.transition().duration(100);
var transoneMini = mini.transition().duration(100);
var categoriesone = transoneMain.selectAll(".category");
categoriesone.selectAll("rect")
.attr("y", function(d) { return this.getBBox().y + this.getBBox().height - (yScaleLeft(d.y0) - yScaleLeft(d.y1)) })
.attr("height", function(d) { return yScaleLeft(d.y0) - yScaleLeft(d.y1); });
var miniCategoriesone = transoneMini.selectAll(".mini_category");
miniCategoriesone.selectAll("rect")
.attr("y", function(d) { return this.getBBox().y + this.getBBox().height - (miniyScaleLeft(d.y0) - miniyScaleLeft(d.y1)) })
.attr("height", function(d) { return miniyScaleLeft(d.y0) - miniyScaleLeft(d.y1); });
var transtwoMain = transoneMain.transition()
.delay(150)
.duration(200)
.ease("bounce");
var transtwoMini = transoneMini.transition()
.delay(150)
.duration(200)
.ease("bounce");
var categoriestwo = transtwoMain.selectAll(".category");
categoriestwo.selectAll("rect")
.attr("y", function(d) { return yScaleLeft(d.y1); });
var miniCategoriestwo = transtwoMini.selectAll(".mini_category");
miniCategoriestwo.selectAll("rect")
.attr("y", function(d) { return miniyScaleLeft(d.y1); });
yAxisLeft.tickFormat(d3.format(".2s"));
main.selectAll(".y.axisLeft").call(yAxisLeft);
}
function brushed() {
xscale.domain(brush.empty() ? miniXScale.domain() : brush.extent());
main.selectAll(".category")
.attr("transform", function(d) { return "translate(" + xscale(+d.CategoryNames) + ",0)"; });
main.selectAll(".line")
.data(convertedData)
.attr("d", function(d) { return line(convertedData); })
main.select("g.x.axis")
.call(xaxis)
.selectAll("text")
.attr("y", 5)
.attr("x", 7)
.attr("dy", ".35em")
.attr("transform", "rotate(65)")
.style("text-anchor", "start");
}
d3.select(self.frameElement).style("height", (height + mainMargin.top + mainMargin.bottom) + "px");
}