Reputation: 139
Im trying to create something roughly in the same vein as -
currently my code has produced something like this -
while crude and simple, serves its purpose, and can be tidied up later. the problem im having is plotting the data. I've seen multiple examples using d3.svg.line() but all seem to use one data set.
The code responsible for the axis' is -
<html>
<head>
<title>D3 Axis Example</title>
<script src="http://d3js.org/d3.v3.js"></script>
<style type="text/css">
</style>
</head>
<body>
<script>
var margin = {top: 100, right: 100, bottom: 100, left: 100},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var conditions = ['condition 1', 'condition 2', 'condition 3', 'condition 4', 'condition 6','condition 7', 'condition 8', 'condition 9', 'condition 10']
var frequency = [3000, 21, 70, 10, 20, 19, 18, 34, 2]
var x = d3.scale.ordinal()
.domain(conditions)
.rangePoints([0, width]);
var y = d3.scale.linear().domain([0, d3.max(frequency)]).range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxisLeft = d3.svg.axis()
.scale(y)
.ticks(4)
.orient("left");
// creating the line
var line = d3.svg.line()
.x(function(d,i) {
return x(i);
})
.y(function(d) {
return y(d);
})
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 + "," + (height + 25) +")");
svg.append("g")
.attr("class", "xaxis")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,-300)")
.call(yAxisLeft);
svg.selectAll(".xaxis text") // select all the text elements for the xaxis
.attr("transform", function(d) {
return "translate(" + this.getBBox().height*-2 + "," + this.getBBox().height + ")rotate(-45)";
})
.attr('y', '50')
.attr('x', '-50')
svg.append("path").attr("d", line(frequency));
</script>
</body>
</html>
is there a way i am able to plot a line using two datasets, or maybe combine both into one usable dataset and do it that way?
Upvotes: 1
Views: 570
Reputation: 102174
The first parameter (d
) in the anonymous function inside the line generator is the datum referring to the data array you pass to that function. However, the second parameter (i
) is simply the index, and it is of course the same regardless the array you use.
Thus, the solution is using those indices to get the values of the second array:
var line = d3.svg.line()
.x(function(d, i) {
return x(conditions[i]);
//data array------^
})
.y(function(d) {
return y(d);
})
Have in mind that, for this to work, you have to be sure about the order of the elements in both arrays.
Here is your updated code:
var margin = {
top: 20,
right: 20,
bottom: 100,
left: 40
},
width = 800 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var conditions = ['condition 1', 'condition 2', 'condition 3', 'condition 4', 'condition 6', 'condition 7', 'condition 8', 'condition 9', 'condition 10']
var frequency = [3000, 21, 70, 10, 20, 19, 18, 34, 2]
var x = d3.scale.ordinal()
.domain(conditions)
.rangePoints([margin.left, width]);
var y = d3.scale.linear().domain([0, d3.max(frequency)]).range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxisLeft = d3.svg.axis()
.scale(y)
.ticks(4)
.orient("left");
// creating the line
var line = d3.svg.line()
.x(function(d, i) {
return x(conditions[i]);
})
.y(function(d) {
return y(d);
})
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", "xaxis")
.attr("transform", "translate(0,"+ (height) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "yaxis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxisLeft);
svg.selectAll(".xaxis text") // select all the text elements for the xaxis
.attr("transform", function(d) {
return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + ")rotate(-45)";
})
.attr('y', '10')
.attr('x', '-10')
svg.append("path").attr("d", line(frequency))
.attr("fill", "none")
.attr("stroke", "orange");
.xaxis line,
.xaxis path,
.yaxis line,
.yaxis path {
fill: none;
stroke: black;
}
<script src="https://d3js.org/d3.v3.js"></script>
PS: I changed the margins, the axes and the scales.
Upvotes: 1