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
Related
I am rendering a horizontal bars graph as below.
I am unable to display, the bottom most tick of y-axis. how to display bottom most tick on y-axis ?
I have increased the height of the svg, height, because of which height is increasing, but tick still not visible.
var data = [
{ name: "0-18", value: 0.07507 },
{ name: "19-30", value: 0.01492 },
{ name: "31-50", value: 0.02782 },
{ name: "51-70", value: 0.04253 },
];
var margin = { left: 100, top: 10, right: 10, bottom: 100 };
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var x = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.value)])
.range([margin.left, width]);
var y = d3
.scaleBand()
.domain(d3.range(data.length))
.rangeRound([margin.top, height])
.padding(0.2);
svg
.append("g")
.attr("class", "y-axis")
.attr("transform", `translate(${margin.left}, 0)`)
.call(
d3
.axisLeft(y)
.tickFormat((i) => data[i].name)
.tickSizeOuter(10)
);
svg
.append("g")
.attr("fill", "steelblue")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", x(0))
.attr("y", (d, i) => y(i))
.attr("width", (d) => x(d.value) - x(0))
.attr("height", y.bandwidth());
svg
.append("g")
.attr("fill", "white")
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.selectAll("text")
.data(data)
.join("text")
.attr("x", (d) => x(d.value) - 4)
.attr("y", (d, i) => y(i) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.text((d) => d3.format(".0%")(d.value));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
Just amend rangeRound() second value for y to be like this:
.rangeRound([margin.top, height - margin.top ])
to understand more about margin convention check this article on observable for margin convention, here is a working snippet:
var data = [
{ name: "0-18", value: 0.07507 },
{ name: "19-30", value: 0.01492 },
{ name: "31-50", value: 0.02782 },
{ name: "51-70", value: 0.04253 },
];
var margin = { left: 100, top: 10, right: 10, bottom: 100 };
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var x = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.value)])
.range([margin.left, width]);
var y = d3
.scaleBand()
.domain(d3.range(data.length))
.rangeRound([margin.top, height - margin.top ])
.padding(0.2);
svg
.append("g")
.attr("class", "y-axis")
.attr("transform", `translate(${margin.left}, 0)`)
.call(
d3
.axisLeft(y)
.tickFormat((i) => data[i].name)
.tickSizeOuter(10)
);
svg
.append("g")
.attr("fill", "steelblue")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", x(0))
.attr("y", (d, i) => y(i))
.attr("width", (d) => x(d.value) - x(0))
.attr("height", y.bandwidth());
svg
.append("g")
.attr("fill", "white")
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.selectAll("text")
.data(data)
.join("text")
.attr("x", (d) => x(d.value) - 4)
.attr("y", (d, i) => y(i) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.text((d) => d3.format(".0%")(d.value));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
Substracting margin.top to height in the rangeRound definition is one way to fix the problem.
This is necessary because the SVG is created with a height where the margin value has already been substracted.
var y = d3
.scaleBand()
.domain(d3.range(data.length))
.rangeRound([margin.top, height - margin.top])
Demo in the snippet below.
var data = [
{ name: "0-18", value: 0.07507 },
{ name: "19-30", value: 0.01492 },
{ name: "31-50", value: 0.02782 },
{ name: "51-70", value: 0.04253 },
];
var margin = { left: 100, top: 10, right: 10, bottom: 100 };
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var x = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.value)])
.range([margin.left, width]);
var y = d3
.scaleBand()
.domain(d3.range(data.length))
.rangeRound([margin.top, height - margin.top])
.padding(0.2);
svg
.append("g")
.attr("class", "y-axis")
.attr("transform", `translate(${margin.left}, 0)`)
.call(
d3
.axisLeft(y)
.tickFormat((i) => data[i].name)
.tickSizeOuter(10)
);
svg
.append("g")
.attr("fill", "steelblue")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", x(0))
.attr("y", (d, i) => y(i))
.attr("width", (d) => x(d.value) - x(0))
.attr("height", y.bandwidth());
svg
.append("g")
.attr("fill", "white")
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.selectAll("text")
.data(data)
.join("text")
.attr("x", (d) => x(d.value) - 4)
.attr("y", (d, i) => y(i) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.text((d) => d3.format(".0%")(d.value));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
I'm using this tutorial, Making a cool Bitcoin price chart using D3.js and the CryptoCompare API and I am having trouble styling the lines that are drawn.
For example, I would like to be able to select and style the lines x and y to change their color to white. See this snippet from the tutorial:
var x = d3.scaleTime()
.range([0, width])
I've tried adding .attr("fill", "#fff"), but this only breaks it. How do I change the colors of d3.scaleTime() and d3.scaleLinear()?
I have also tried the following as described in the d3-scale documentation:
var x = d3.scaleTime()
.range([0, width])
x(20); // "#9a3439"
Here's the entire script:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>
</head>
<style>
body {
text-align: center;
margin-top: 5em;
background-color: #74b9ff;
}
h1 {
color: snow;
}
</style>
<body>
<h1>Bitcoin Prices in U.S. Dollars</h1>
<script>
var url = "https://min-api.cryptocompare.com/data/histoday?fsym=BTC&tsym=USD&limit=200&aggregate=3&e=CCCAGG";
d3.json(url).get(function(error, d) {
var data = d.Data;
data.forEach(function(d){ d.time = new Date(d.time * 1000) });
if (error) throw error;
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleTime()
.range([0, width])
var y = d3.scaleLinear()
.range([height, 0]);
var line = d3.line()
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.close); });
x.domain(d3.extent(data, function(d) { return d.time; }));
y.domain(d3.extent(data, function(d) { return d.close; }));
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.attr("stroke-width", 2)
.attr("fill", "none")
.style("font-size",".8em");
g.append("g")
.call(d3.axisLeft(y))
.attr("stroke-width", 2)
.style("font-size",".8em")
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 20)
.attr("text-anchor", "end")
.attr("font-size", "1.2em")
.text("Price ($)")
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ffeaa7")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 2)
.attr("d", line);
});
</script>
</body>
</html>
You can style the axes as shown below.
var xAxis = g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
xAxis.select("path") //Axis
.style("stroke","white");
xAxis.selectAll("line") //ticks
.style("stroke","white");
var yAxis = g.append("g")
.call(d3.axisLeft(y));
yAxis.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 20)
.attr("text-anchor", "end")
.attr("font-size", "1.2em")
.text("Price ($)");
yAxis.select("path") //Axis
.style("stroke","white");
yAxis.selectAll("line") //ticks
.style("stroke","white");
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>
</head>
<style>
body {
text-align: center;
margin-top: 5em;
background-color: #74b9ff;
}
h1 {
color: snow;
}
</style>
<body>
<h1>Bitcoin Prices in U.S. Dollars</h1>
<script>
var url = "https://min-api.cryptocompare.com/data/histoday?fsym=BTC&tsym=USD&limit=200&aggregate=3&e=CCCAGG";
d3.json(url).get(function(error, d) {
var data = d.Data;
data.forEach(function(d) {
d.time = new Date(d.time * 1000)
});
if (error) throw error;
var svg = d3.select("svg"),
margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleTime()
.range([0, width])
var y = d3.scaleLinear()
.range([height, 0]);
var line = d3.line()
.x(function(d) {
return x(d.time);
})
.y(function(d) {
return y(d.close);
});
x.domain(d3.extent(data, function(d) {
return d.time;
}));
y.domain(d3.extent(data, function(d) {
return d.close;
}));
var xAxis = g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.attr("stroke-width", 2)
.attr("fill", "none")
.style("font-size", ".8em")
xAxis.select("path") //Axis
.style("stroke", "white");
xAxis.selectAll("line") //ticks
.style("stroke", "white");
var yAxis = g.append("g")
.call(d3.axisLeft(y))
.attr("stroke-width", 2)
.style("font-size", ".8em");
yAxis.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 20)
.attr("text-anchor", "end")
.attr("font-size", "1.2em")
.text("Price ($)");
yAxis.select("path") //Axis
.style("stroke", "white");
yAxis.selectAll("line") //ticks
.style("stroke", "white");
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ffeaa7")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 2)
.attr("d", line);
});
</script>
</body>
</html>
While Gilsha's answer seems like best practice and allows for more direct control over styling, the answer got from that was to use selectAll() to select and style each "path" (axes), "line" (ticks), and "text" (display of price and date).
Including the following in the end of the function d3.json(url).get(function(error, d) styles everything as white:
g.selectAll("path") //Axes
.style("stroke","white");
g.selectAll("line") //Ticks
.style("stroke","white");
g.selectAll("text") //Text displaying date and price
.attr("fill", "white");
Note that this broad-stroke approach includes the path for the plotted data line as well. If you need to distinguish between them, you can define a variable for that and style it independently as Gilsha did for the 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 am making a scatterplot, and pulling in an image fill for each circle on the plot. The problem is that the images are PNG's with transparent backgrounds. This means my overlapping circles show through each other:
Seen here - http://i.stack.imgur.com/bphon.png
I have tried setting a background colour with the CSS, but it seems to be completely overwritten by the .style("fill") in the JS. And I am looking to pull in 30ish images, so I don't want to have to save them all to be able to load the images with my CSS.
So, my question is, is there a way to put a white background behind my PNGs, while pulling those PNGs from URL's contained in my dataset?
Thanks for the help
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style type="text/css">
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis-text {
font-family: sans-serif;
font-size: 11px;
background-color: white;
font-weight: bold;
}
.teamcircle {
background-color: white;
}
</style>
</head>
<body>
<div>
<input type="button" id="playerbtn" value="See Player View">
<input type="button" id="teambtn" value="See Team View">
</div>
<div id="data">
<div id="player-circles">
</div>
</div>
<script type="text/javascript">
//Width and height
var margin = {top: 50, right: 20, bottom: 30, left: 40};
var w = 960 - margin.left - margin.right;
var h = 500 - margin.top - margin.bottom;
//Create scale functions
var xScale = d3.scale.linear()
.range([0, w]);
var yScale = d3.scale.linear()
.range([h, 0]);
// var color = d3.scale.color();
// Define the Axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
//Create SVG element
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 + ")");
//Load the TEAM data set
var teamdata = d3.tsv("team.tsv", function(error, teamdata) {
if (error) throw error;
teamdata.forEach(function(d) {
d.entriesper60 = +d.entriesper60;
d.carryinpercent = +d.carryinpercent;
});
xScale.domain(d3.extent(teamdata, function(d) { return d.carryinpercent; })).nice();
yScale.domain(d3.extent(teamdata, function(d) { return d.entriesper60; })).nice();
//Create X axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis)
.append("text")
.attr("class", "axis-text")
.attr("x", w)
.attr("y", -6)
.style("text-anchor", "end")
.text("Carry-in %");
//Create Y axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "axis-text")
.attr("y", -20)
.attr("z", 0)
.style("text-anchor", "middle")
.text("Entries/60")
// DEFS & Pattern for images
svg.append("defs")
.selectAll("pattern")
.data(teamdata)
.enter()
.append("pattern")
.attr('id', function(d, i) {
return d.name;
})
// .attr('patternUnits', 'userSpaceOnUse')
.attr('width', 20)
.attr('height', 20)
.append("image")
.attr("xlink:href", function(d) {
return d.image + d.name;
})
.attr('width', 20)
.attr('height', 20)
.attr("transform", "translate(2, 2)");
// Create TEAM Circles
svg.selectAll("circle")
.data(teamdata)
.enter()
.append("circle")
.attr("class", "teamcircle")
.style("stroke", function(d) { return d.hex; })
.style("stroke-width", 2)
.style("stroke-opacity", .8)
.attr("r", 12)
.attr("cx", function(d) { return xScale(d.carryinpercent); })
.attr("cy", function(d) { return yScale(d.entriesper60); })
.attr("fill", function(d) { return "url(#" + d.name + ")";
});
});
</script>
</body>
</html>
The best way I can think of is to create a group for every circle, and create a circle with a white background first. Something like this:
var teamCircle = svg.selectAll("g.teamcircle")
.data(teamdata)
.enter()
.append("g")
.attr("class", "teamcircle")
.transform(function(d){return "translate(" + xScale(d.carryinpercent) + "," + yScale(d.entriesper60) + ")"});
teamCircle.append("circle")
.attr("fill", "white")
.attr("r", 12)
teamCircle.append("circle")
.style("stroke", function(d) { return d.hex; })
.style("stroke-width", 2)
.style("stroke-opacity", .8)
.attr("r", 12)
.attr("fill", function(d) { return "url(#" + d.name + ")";
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")