Reputation: 458
I have been trying to implement a Line-Bar Combo Chart but I'm not much successfull. Here's my code
function renderNormalizedStackBarChart(inputData,dom_element_to_append_to, path_to_data) {
var margin = {top: 20, right: 231, bottom: 140, left: 40},
width = $(dom_element_to_append_to).width() - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var xscale = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var yScaleLeft = d3.scale.linear()
.rangeRound([height, 0]);
var yScaleRight = d3.scale.linear()
.rangeRound([height, 0]);
var colors = d3.scale.ordinal()
.range(["#63c172", "#ee9952", "#46d6c4", "#fee851", "#98bc9a"]);
var xaxis = d3.svg.axis()
.scale(xscale)
.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 x = d3.time.scale()
.range([0, width - 25]);
/*category.selectAll("rect")
.data(function(d) { return d.responses; })
.enter().append("rect")
.attr("width", xscale.rangeBand())
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
.style("fill", function(d) { return colors(d.response); });*/
var temp = 0;
var line = d3.svg.line()
.x(function(d, i) {
console.log(temp);
var temp2 = temp;
temp += xscale.rangeBand();
return temp2;
})
.y(function(d) {
console.log(yScaleRight(d.value));
return yScaleRight(d.value);
})
.interpolate("linear")
;
var svg = d3.select(dom_element_to_append_to).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.tsv(path_to_data, function(error, data) {
//data = inputData;
var categories = d3.keys(data[0]).filter(function(key) { return key !== "CategoryNames"; });
var parsedata = categories.map(function(name) { return { "CategoryNames": name }; });
data.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;
return responseobj;
});
pd.responses.forEach(function(d) { d.yp0 /= y0; d.yp1 /= y0; });
pd.totalresponses = pd.responses[pd.responses.length - 1].y1;
});
console.log(parsedata);
xscale.domain(parsedata.map(function(d) { return d.CategoryNames; }));
svg.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");
svg.append("g")
.attr("class", "y axisLeft")
.call(yAxisLeft);
svg.append("g")
.attr("class", "y axisRight")
.attr("transform", function() { return "translate(" + width + "," + 0 + ")"; })
.call(yAxisRight);
var category = svg.selectAll(".category")
.data(parsedata)
.enter().append("g")
.attr("class", "category")
.attr("transform", function(d) { return "translate(" + xscale(d.CategoryNames) + ",0)"; });
category.selectAll("rect")
.data(function(d) { return d.responses; })
.enter().append("rect")
.attr("width", xscale.rangeBand())
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); })
.style("fill", function(d) { return colors(d.response); });
var convertedData = [];
parsedata.forEach(function(item) {
convertedData.push({response: item.CategoryNames, value: item.responses[0].yp1})
});
temp = xscale.rangeBand()/2;
console.log(convertedData);
svg.append("path")
.data(convertedData)
.attr("class", "line")
.attr("d", line(convertedData));
var legend = svg.selectAll(".legend")
.data(colors.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(82," + ((height - 18) - (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; });
d3.selectAll("input").on("change", handleFormClick);
function handleFormClick() {
if (this.value === "bypercent") {
transitionPercent();
} else {
transitionCount();
}
}
function transitionPercent() {
yScaleLeft.domain([0, 1]);
var trans = svg.transition().duration(250);
var categories = trans.selectAll(".category");
categories.selectAll("rect")
.attr("y", function(d) { return yScaleLeft(d.yp1); })
.attr("height", function(d) { return yScaleLeft(d.yp0) - yScaleLeft(d.yp1); });
yAxisLeft.tickFormat(d3.format(".0%"));
svg.selectAll(".y.axisLeft").call(yAxisLeft);
}
function transitionCount() {
yScaleLeft.domain([0, d3.max(parsedata, function(d) { return d.totalresponses; })]);
var transone = svg.transition()
.duration(100);
var categoriesone = transone.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 transtwo = transone.transition()
.delay(150)
.duration(200)
.ease("bounce");
var categoriestwo = transtwo.selectAll(".category");
categoriestwo.selectAll("rect")
.attr("y", function(d) { return yScaleLeft(d.y1); });
yAxisLeft.tickFormat(d3.format(".2s"));
svg.selectAll(".y.axisLeft").call(yAxisLeft);
}
});
d3.select(self.frameElement).style("height", (height + margin.top + margin.bottom) + "px");
}
var inputData = [];
renderNormalizedStackBarChart(inputData,"#normalizedChart", "data/normalizedChart.tsv");
rect.bordered {
stroke: #E6E6E6;
stroke-width: 2px;
}
body {
font-size: 9pt;
font-family: Consolas, courier;
}
text.axis {
fill: #000;
}
.axisLeft path,
.axisLeft line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axisRight path,
.axisRight line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
.legend line {
stroke: #000;
shape-rendering: crispEdges;
}
path .line {
stroke: #000;
shape-rendering: crispEdges;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div class="row">
<form>
<label><input type="radio" name="mode" value="bypercent" checked> Percent</label>
<label><input type="radio" name="mode" value="bycount"> Number of Respondants</label>
</form>
<div id="normalizedChart"></div>
</div>
but all I'm getting is the graph shown in the image below. How to make the path appear as line.Here in the code InputData variable is of no use as I'm reading data through a tsv file.
Upvotes: 0
Views: 178
Reputation: 1983
You have to add the style to your fill : none
to your path
svg.append("path")
.data(convertedData)
.attr("class", "line")
.attr("d", line(convertedData));
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
Upvotes: 1