I need to draw axis grid lines only inside areas in Area Chart, written in D3 (version 4) .
Have any solutionss of this issue?
Use negative width and height for the axis tick length
And then use a CSS style to stroke the grid.
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.call(d3.axisLeft(y));
g.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickSize(-height)
.tickFormat("")
);
g.append("g")
.attr("class", "grid")
.call(d3.axisLeft(y)
.tickSize(-width)
.tickFormat("")
);
Edit
If it is inside the Area define a clipping path that equals the area and group the grid lines to this clipping path.
Using the example from https://www.mattlayman.com/blog/2015/d3js-area-chart/
var data = [
{ x: 0, y: 10, },
{ x: 1, y: 15, },
{ x: 2, y: 35, },
{ x: 3, y: 20, },
];
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 575 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.x; })])
.range([0, width]);
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.y; })])
.range([height, 0]);
var xAxis = d3.axisBottom()
.scale(x);
var yAxis = d3.axisLeft()
.scale(y);
var area = d3.area()
.x(function(d) { return x(d.x); })
.y0(height)
.y1(function(d) { return y(d.y); });
var svg = d3.select("svg#area")
.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("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("clipPath")
.attr("id", "area-clip")
.append("path")
.attr("d", area(data));
var grid = svg.append("g")
.attr("clip-path","url(#area-clip)");
grid.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(xAxis.tickSize(-height).tickFormat(""));
grid.append("g")
.attr("class", "grid")
.call(yAxis.tickSize(-width).tickFormat(""));
.area {fill:steelblue;}
.grid line {fill:none; stroke:red; stroke-width:1;}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg id="area"></svg>
Related
I am new to d3 and having issue with showing the label of ordinal axis:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta charset="utf-8">
<title>D3: Loading data from a CSV file</title>
</head>
<body>
<script type="text/javascript">
var margin = {top: 20, right: 20, bottom: 30, left: 40},
w = 600 - margin.left - margin.right,
h = 300 - margin.top - margin.bottom;
var padding = 40;
var data = [
{ "Food": "Apples", "Deliciousness": 9 },
{ "Food": "Green Beans", "Deliciousness": 5 },
{ "Food": "Egg Salad Sandwich", "Deliciousness": 4 },
{ "Food": "Cookies", "Deliciousness": 10 },
{ "Food": "Liver", "Deliciousness": 2 },
{ "Food": "Burrito", "Deliciousness": 7 },
];
data.forEach(function(d) {
d.Deliciousness = +d.Deliciousness;
});
var svg = d3.select("body")
.append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left+"," +
margin.top+")");
var xScale = d3.scaleBand()
.domain(d=>d.Food)
.range([0,w])
.paddingInner(0.2);
xScale.domain(data.map(function(d) { return d.Food; }));
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d=>d.Deliciousness)])
.rangeRound([h,0]);
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x',(d,i) => margin.left + i*w/data.length)
.attr('y',d=>yScale(d.Deliciousness))
.attr('width', xScale.bandwidth())
.attr('height',d =>h-yScale(d.Deliciousness))
.attr('fill',function(d){
if (d===30) return "red";
return "rgb(0,0,"+d.Deliciousness*10+")" ;});
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(d=>d.Deliciousness)
.attr("x", (d,i)=>(padding + i*w/data.length))
.attr("y", d=>yScale(d.Deliciousness)+15)
.attr("fill","white");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h-margin.bottom) + ")")
.call(xAxis);
</script>
</body>
</html>
The x axis is somehow overlapping with the chart, how to properly use the margin?
And in terms of ordinal axis, other than list all the categories manually in .domain(), what are the other ways to special xScale in .domain().range() call? Thanks
It comes from the location definition of the x-axis.
You can change:
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h-margin.bottom) + ")")
.call(xAxis);
with:
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + margin.left + "," + h + ")")
.call(xAxis);
Here is the demo:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<meta charset="utf-8">
<title>D3: Loading data from a CSV file</title>
</head>
<body>
<script type="text/javascript">
var margin = {top: 20, right: 20, bottom: 30, left: 40},
w = 600 - margin.left - margin.right,
h = 300 - margin.top - margin.bottom;
var padding = 40;
var data = [
{ "Food": "Apples", "Deliciousness": 9 },
{ "Food": "Green Beans", "Deliciousness": 5 },
{ "Food": "Egg Salad Sandwich", "Deliciousness": 4 },
{ "Food": "Cookies", "Deliciousness": 10 },
{ "Food": "Liver", "Deliciousness": 2 },
{ "Food": "Burrito", "Deliciousness": 7 },
];
data.forEach(function(d) {
d.Deliciousness = +d.Deliciousness;
});
var svg = d3.select("body")
.append("svg")
.attr("width", w + margin.left + margin.right + padding)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left+"," +
margin.top+")");
var xScale = d3.scaleBand()
.domain(d=>d.Food)
.range([0,w])
.paddingInner(0.2);
xScale.domain(data.map(function(d) { return d.Food; }));
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d=>d.Deliciousness)])
.rangeRound([h,0]);
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x',(d,i) => margin.left + i * ((w + 20 ) / data.length))
.attr('y',d=>yScale(d.Deliciousness))
.attr('width', xScale.bandwidth())
.attr('height',d =>h-yScale(d.Deliciousness))
.attr('fill',function(d){
if (d===30) return "red";
return "rgb(0,0,"+d.Deliciousness*10+")" ;});
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(d=>d.Deliciousness)
.attr('x',(d,i) => margin.left + i * ((w + 20 ) / data.length))
.attr("y", d=>yScale(d.Deliciousness)+15)
.attr("fill","white");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + margin.left + "," + h + ")")
.call(xAxis);
</script>
</body>
</html>
x-axis location compared to its container (here svg) is defined by the transform attribute. Which in this case is a translation. To define a translation, we give to the transform attribute this value: translate(dx,dy).
dx: As rects are given a x offset of margin.left (.attr('x',(d,i) => margin.left + i*w/data.length)) we also need to translate the x-axis horizontally by margin.left.
dy: And as rects have their base starting at h (.rangeRound([h, 0]);), we also need to translate the x-axis vertically by h.
I have also modified the x position of bars and labels using:
.attr('x',(d,i) => margin.left + i * ((w + margin.right ) / data.length))
instead of:
.attr('x',(d,i) => margin.left + i*w/data.length)
Finally, as the last bar is half outside the graph, you can increase the svg container's width, by replacing:
.attr("width", w + margin.left + margin.right)
with:
.attr("width", w + margin.left + margin.right + padding)
Concerning your final question, this https://github.com/d3/d3-axis might give you additional details on how to use d3 axes.
I am trying to create a simple multi-line chart using JSON data similar to the following:
[
{
sampleDate: "2014-04-14",
shortName: "PFOA",
pfcLevel: "0.3500000"
},
{
sampleDate: "2014-05-14",
shortName: "PFOA",
pfcLevel: "0.3200000"
},
{
sampleDate: "2014-04-14",
shortName: "PFOS",
pfcLevel: "2.5000000"
},
{
sampleDate: "2014-05-14",
shortName: "PFOS",
pfcLevel: "2.4000000"
}
]
I have basic X and Y axis showing, but the actual value lines are not displaying. Looking at the DOM the path element is not showing the d attribute.
<path class="line" style="stroke: green;"></path>
The code is below:
<script>
var data = <?php echo $wellSamples ?>;
console.log(data);
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%Y-%m-%d").parse;
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { console.log(d.sampleDate); return x(d.sampleDate); })
.y(function(d) { console.log(d.pfcLevel); return y(d.pfcLevel); });
var svg = d3.select("#chart").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 + ")");
x.domain(d3.extent(data, function(d) { return parseDate(d.sampleDate); }));
y.domain(d3.extent(data, function(d) { return d.pfcLevel; }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
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("PFC Level");
var pfc = svg.selectAll(".pfc")
.data(data)
.enter().append("g")
.attr("class", "pfc");
pfc.append("path")
.attr("class", "line")
.attr("d", line)
.style("stroke", "green");
</script>
Several problems here:
Your data-binding is invalid. You bind the data then call .attr("d", line), this would call the line function on each point. It needs awhole array -- .attr("d", line(data))
You've made no attempt to create more then one line from that data. I'm guessing you want a line per "shortName"? You need to nest the data.
Your line x accessor calls .x(function(d) { return x(d.sampleDate); }), d.sampleDate has never been converted to a date though, it's still a string.
Putting this all together:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div id="chart"></div>
<script>
var data = [
{
sampleDate: "2014-04-14",
shortName: "PFOA",
pfcLevel: "0.3500000"
},
{
sampleDate: "2014-05-14",
shortName: "PFOA",
pfcLevel: "0.3200000"
},
{
sampleDate: "2014-04-14",
shortName: "PFOS",
pfcLevel: "2.5000000"
},
{
sampleDate: "2014-05-14",
shortName: "PFOS",
pfcLevel: "2.4000000"
}
];
// Parse the date / time
var parseDate = d3.time.format("%Y-%m-%d").parse;
// clean up data
data.forEach(function(d){
d.sampleDate = parseDate(d.sampleDate);
d.pfcLevel = +d.pfcLevel;
});
// nest data
var nested_data = d3.nest()
.key(function(d) { return d.shortName; })
.entries(data);
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.sampleDate); })
.y(function(d) { return y(d.pfcLevel); });
var svg = d3.select("#chart").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 + ")");
x.domain(d3.extent(data, function(d) { return d.sampleDate; }));
y.domain(d3.extent(data, function(d) { return d.pfcLevel; }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
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("PFC Level");
// now we bind to nested_data, an array of arrays
var pfc = svg.selectAll(".pfc")
.data(nested_data)
.enter()
.append("g")
.attr("class", "pfc");
pfc.append("path")
.attr("class", "line")
.attr("d", function(d){
// our inner array is d.values from the nesting
return line(d.values);
})
.style("stroke", "green");
</script>
</body>
</html>
I try to adapt the following script.
But unfortunately I can not match the data points to the legend on the x-axis?
How can I move the data points / the line to the right to match the legend on the x-axis?
Source is: http://mund-consulting.com/Blog/visualizing-web-page-views-using-d3js/
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>
var margin = { top: 40, right: 20, bottom: 30, left: 40 },
width = 900,
height = 400;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
return "<strong>"+d.MonthName+": </strong>
<span style='color:black'>" + d.PageViews + "</span>";
})
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.call(tip);
d3.csv("mc_monthly_pageview_2014.csv", function (error, data) {
x.domain(data.map(function (d) { return d.MonthName; }));
y.domain([0, d3.max(data, function (d) { return d.PageViews; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
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("Page Views");
var line = d3.svg.line()
.x(function (d) { return x(d.MonthName); })
.y(function (d) { return y(d.PageViews); });
svg.selectAll("path.line")
.data(data)
.enter()
.append("path")
.attr("class", "line")
.attr("d", line(data));
svg.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function (d) { return x(d.MonthName); })
.attr("cy", function (d) { return y(d.PageViews); })
.attr("r", 4.5)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
});
</script>
I found a solution.
Exchange
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
with
var x = d3.scale.ordinal()
.rangePoints([0, width]);
I am creating a D3 bar chart using below code .
<head>
<style>
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
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 = [{"text":"A","value":50,"linkurl":"http://google.com"}, {"text":"B","value":100,"linkurl":"http://php.net"},{"text":"C","value":150,"linkurl":"http://drupal.org"}]
data.forEach(function(d) {
d.text = d.text;
d.value = +d.value;
d.linkurl = d.linkurl;
});
x.domain(data.map(function(d) { return d.text; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-45)" );
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("");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function(d) { return x(d.text); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
svg.on("click", function (d) { //<-D
//var position = d3.mouse(svg.node());
window.location.href='http://google.com';
//window.location.href=d.linkurl;
});
</script>
</body>
And want to create a link on each bar.. for that I am using the code . It is working fine when I am using same URL for each bar but doesn't
for different URl for each bar...
var data = [{"text":"A","value":50,"linkurl":"http://google.com"},{"text":"B","value":100,"linkurl":"http://php.net"},{"text":"C","value":150,"linkurl":"http://drupal.org"}]
data.forEach(function(d) {
d.text = d.text;
d.value = +d.value;
d.linkurl = d.linkurl;
});
svg.on("click", function (d) { //<-D
//var position = d3.mouse(svg.node());
window.location.href='http://google.com';
//window.location.href=d.linkurl;
});
You have to bind the click listener to the bars (rectangles) instead of svg.
var bars = svg.selectAll("bar")
.data(data)
.enter()
.append("rect")
.style("fill", "steelblue")
.attr("x", function(d) {
return x(d.text);
}).attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.value);
}).attr("height", function(d) {
return height - y(d.value);
});
bars.on("click", function(d) {
window.location.href = d.linkurl;
});
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
}, width = 600 - margin.left - margin.right, height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([ 0, width ], .05);
var y = d3.scale.linear().range([ height, 0 ]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10);
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 = [ {
text: "A",
value: 50,
linkurl: "http://google.com"
}, {
text: "B",
value: 100,
linkurl: "http://php.net"
}, {
text: "C",
value: 150,
linkurl: "http://drupal.org"
} ];
data.forEach(function(a) {
a.text = a.text;
a.value = +a.value;
a.linkurl = a.linkurl;
});
x.domain(data.map(function(a) {
return a.text;
}));
y.domain([ 0, d3.max(data, function(a) {
return a.value;
}) ]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-45)");
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("");
var bars = svg.selectAll("bar")
.data(data)
.enter()
.append("rect")
.style("fill", "steelblue")
.attr("x", function(a) {
return x(a.text);
}).attr("width", x.rangeBand())
.attr("y", function(a) {
return y(a.value);
}).attr("height", function(a) {
return height - y(a.value);
});
bars.on("click", function(a) {
window.location.href = a.linkurl;
});
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
The codes are the following: I am trying to create two "div" .Each div has a picture. However, the pictures are collapsing together after all the texts. They do not stay in their individual div.
<div class="container">
<div class ="row">
<h1> Title </h1>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" >
var margin = {top: 20, right: 30, bottom: 30, left: 100},
width = 800 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var formato = d3.format("0.0");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(formato);
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 dataFile_1 = "data.csv"
d3.csv(dataFile_1, function(error1, data1) {
data1.forEach(function(d) {
d.petitionRate = +d.petitionRate;
});
x.domain(data1.map(function(d) { return d.state; }));
y.domain([0, d3.max(data1, function(d) { return d.petitionRate; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
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("Participation rate");
svg.selectAll(".bar")
.data(data1)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.state); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.petitionRate); })
.attr("height", function(d) { return height - y(d.petitionRate)});
</div>
<div class ="row">
If I put a picture here as the first one. Both of them do not stay in their div.
</div>
</div>
Please help me understand what the problem is here.
Thanks.
This line:
var svg = d3.select("body").append("svg")
appends d3s svg to the end of the html body. If you want the svg in the
<div class ="row">
directly preceding your JavaScript code do this:
<div class ="row" id="visRow">
and then append to that div:
var svg = d3.select("#visRow").append("svg")