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.
Related
Add the condition issuse
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<script>
// set the dimensions and margins of the graph
const margin = {top: 10, right: 30, bottom: 30, left: 60},
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3.select("#my_dataviz")
.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})`);
//Read the data
d3.csv("https://gist.githubusercontent.com/FANJIYU0825/5626c7449001fc46895412fda1b5c139/raw/9e996d1edec867b2f590285c4e1e769dd482b91c/clean_data").then(function (data) {
// Add X axis
const x = d3.scaleLinear()
.domain([d3.min(data, (d) => d.Rating) - 0.1, d3.max(data, (d) => d.Rating),])
.range([0, width]);
svg.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(x));
// Add Y axis
const y = d3.scaleLinear()
.domain([d3.min(data, (d) => d.Size) - 5, d3.max(data, (d) => d.Size) + 20])
.range([height, 0]);
svg.append("g")
.call(d3.axisLeft(y));
// Add dots
svg.append('g')
.selectAll("dot")
.data(data)
.join("circle")
.attr("cx", (d, i) => {if (d.Category == "BUSINESS") return x(d.Rating);})
.attr("cy", (d, i) => {if (d.Category == "BUSINESS") return y(d.Size);})
.attr("r", 7)
.style("fill", "#69b3a2")
})
</script>
Not add condition look fine
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<script>
// set the dimensions and margins of the graph
const margin = { top: 10, right: 30, bottom: 30, left: 60 },
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3.select("#my_dataviz")
.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})`);
//Read the data
d3.csv("https://gist.githubusercontent.com/FANJIYU0825/5626c7449001fc46895412fda1b5c139/raw/9e996d1edec867b2f590285c4e1e769dd482b91c/clean_data").then(function (data) {
// Add X axis
const x = d3.scaleLinear()
.domain([d3.min(data, (d) => d.Rating) - 0.1, d3.max(data, (d) => d.Rating),])
.range([0, width]);
svg.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(x));
// Add Y axis
const y = d3.scaleLinear()
.domain([d3.min(data, (d) => d.Size) - 5, d3.max(data, (d) => d.Size) + 20])
.range([height, 0]);
svg.append("g")
.call(d3.axisLeft(y));
// Add dots
svg.append('g')
.selectAll("dot")
.data(data)
.join("circle")
.attr("cx", (d, i) => { return x(d.Rating); })
.attr("cy", (d, i) => { return y(d.Size); })
.attr("r", 7)
.style("fill", "#69b3a2")
})
</script>
I get confused becasuse the last part of csv data get wrong position
I am not so sure why the data scale wrong other poitn position is fine but the last data erro no matter what the data is. The scale will show at the part of the top.
At the time that I add the condition.
Other is not different from the sample of
enter link description here
enter image description here
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>
The d3.transition() examples I can find are all using simple arrays of numbers (e.g. var data=[1,3,2,4]), and I wonder what's the proper way to bind real data which has a field on pre-transition state and a field on post-transition state. In the sample below, I intend to transition the values from deliciousness column to new column:
Blockquote
<!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>
<p>Click on this text to update the chart with new data values (once).</p>
<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, "new":4 },
{ "Food": "Green Beans", "Deliciousness": 5, "new":4 },
{ "Food": "Egg Salad Sandwich", "Deliciousness": 4, "new":4 },
{ "Food": "Cookies", "Deliciousness": 10, "new":4 },
{ "Food": "Liver", "Deliciousness": 2, "new":4 },
{ "Food": "Burrito", "Deliciousness": 7, "new":4 },
];
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+")");
//initial state
//scale and axis
var xScale = d3.scaleBand()
.domain(d=>d.Food)
.range([0,w])
.paddingInner(0.2);
xScale.domain(data.map(function(d) { return d.Food; }));
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d=>d.Deliciousness)])
.rangeRound([h,0]);
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
//draw rect
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+")" ;});
//text label
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(d=>d.Deliciousness)
.attr('x',(d,i) => margin.left + i * ((w + 20 ) / data.length) + 0.4*w/ data.length)
.attr("y", d=>yScale(d.Deliciousness)+15)
.attr("fill","white")
.attr("text-anchor", "middle");
//draw axis
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);
//transition
d3.select("p")
.on("click", function() {
//update scale
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d=>d.new)])
.rangeRound([h,0]);
//Update all rects
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x',(d,i) => margin.left + i * ((w + 20 ) / data.length))
.attr('y',d=>yScale(d.new))
.attr('width', xScale.bandwidth())
.attr('height',d =>h-yScale(d.new))
.attr('fill',function(d){
if (d===30) return "red";
return "rgb(0,0,60)" ;});
});
</script>
</body>
</html>
What/s the best data structure to enable transition: are they different column/fields, or passing in two dataset with same column name?
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>
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")