I have a feeling that my main problem is that I just don't know what question to ask. I hope that your suggestions to solve this example problem will point me in the right direction to handle situations like these.
Here's a very simple example I just threw together for the sake of illustration:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
</head>
<body style="background-color:black;">
<div id="viz"></div>
<script type="text/javascript">
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500);
svg.selectAll("circle")
.data([0])
.enter()
.append("circle")
.attr("cx", 250)
.attr("cy", 250)
.attr("r", 30)
.attr("fill", "white");
var m = svg.selectAll("circle.moving")
.data([0])
.enter()
.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 10)
.attr("fill", "red");
repeat();
function repeat() {
m.transition()
.duration(1000)
.ease("linear")
.attr("cx", function(d) { return Math.floor(Math.random()*450);})
.attr("cy", function(d) { return Math.floor(Math.random()*450);})
.each("end", repeat);
}
</script>
</body>
</html>
(source: andrewlaprise.com)
Now let's say I wanted to have something occur every time the red circle collides with the white circle. What if there were a lot of white circles? What if there were a dynamic number of white circles whose positions were controlled by the user?
Should I use some kind of event? I'm new to event-driven programming and I don't have an intuition for it yet.
I suspect the answer to this question will open a lot of doors for me (and at least tell me what I need to google). How should I best listen for that collision?
Related
Here is my code:
<html>
<head>
<meta charset="UTF-8">
<title>circle</title>
</head>
<body>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script>
var width = 400;
var height = 400;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var circle1 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 45)
.style("fill","green");
circle1.transition()
.duration(1000) //延迟1000ms
.attr("cx", 300);
var circle2 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 45)
.style("fill","green");
circle2.transition()
.duration(1500)
.attr("cx", 300)
.style("fill", "red");
var circle3 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 45)
.style("fill","green");
circle3.transition()
.duration(2000)
.transition()
.ease("bounce")
.attr("cx", 300)
.style("fill", "red")
.attr("r", 25);
</script>
</body>
</html>
When I learn how to use the .ease("bounce")in d3 v4.x, the error is always jump out in html:45. In the official introduction: .ease("bounce") now should be used like this:
d3.easeBounce(t)
but it also doesn't work, so I don't know how to modify it. Could you give me a good introduction? Thanks!
The documentation on transition.ease([value]) tells us, that
The value must be specified as a function.
Therefore, you just need to pass in the easing function d3.easeBounce without actually calling it (note, that there are no parentheses following d3.easeBounce):
circle3.transition()
.duration(2000)
.transition()
.ease(d3.easeBounce) // Pass in the easing function
I agree with Altocumulus's answer, but I try to get rid of one of the middle.transition(), and it will run well.
circle3.transition()
.duration(2000)
.ease(d3.easeBounce)
The following is my code. Yet when I run it I get a blank page. Why is this the case ? Also how can I use data from hundreds of columns to make a simple interactive visual using d3 ? I would like to add that the following csv file "LoanStats3a.csv" is in the same folder.
<html>
<title>Loans</title>
<link href="../css/jquery-ui.css" rel="stylesheet" />
<script src="../Scripts/jquery-1.12.4"></script>
<script src="../Scripts/jquery-1.12.4.js"></script>
<script src="../Scripts/jquery-ui.js"></script>
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
<style>
#LoanStats3a{
color: blueviolet;
}
</style>
<body>
<script>
d3.csv("LoanStats3a", function (file1){
var bg = d3.select("body").append("svg")
.attr("width", 5000)
.attr("height", 5000);
bg.selectAll("rect")
.data(file1)
.enter()
.attr("width", function(d){return d.loan_amnt / 100;})
.attr("height", function(d) {return d.term;})
.attr("y", function (d,i) {return i *50;})
.attr("fill", function (d){"red","blue";});
}
</script>
</body>
This is because after binding the data to your empty selection, you have to append a rect element for each data.
Also, your attribute "fill" is incorrect.
bg.selectAll("rect")
.data(file1)
.enter()
.append("rect") // <= You need to create a rect for each data
.attr("width", function(d){return d.loan_amnt / 100;})
.attr("height", function(d) {return d.term;})
.attr("y", function (d,i) {return i *50;})
.attr("fill", "blue");
If you want to change the color depending on the data, create a function and return something.
// For example
.attr("fill", function(d){return d.loan_amnt > 25000 ? "blue" : "red"});
Here's a JsFiddle with random data : DEMO
EDIT : If it's still not working, it's probably a problem with your data because the only thing different between our code is that I used custom data in the JsFiddle.
I notice that your csv file doesn't have the extension .csv, it's just LoanStats3a ?
You should do a console.log(file1), to check if your data are correct.
Take a look at D3 CSV for how to load a csv file.
You are missing a closing ) at the end:
.attr("fill", function (d){"red","blue";});
}
// ^ Here should be a )
</script>
It helps if you have proper indent:
<script>
d3.csv("LoanStats3a", function(file1) {
var bg = d3.select("body").append("svg")
.attr("width", 5000)
.attr("height", 5000);
bg.selectAll("rect")
.data(file1)
.enter()
.attr("width", function(d) {
return d.loan_amnt / 100;
})
.attr("height", function(d) {
return d.term;
})
.attr("y", function(d, i) {
return i * 50;
})
.attr("fill", function(d) {
"red", "blue"; // What is going on here?
// Did you for to return?
// return "blue";
});
});
</script>
I am using D3.js to draw some circles inside a div but for some reason no data is displayed in the bottom third of the did even though the specified size of the canvas is equivalent to the size of the of the div.
var data = d3.csv('circles.csv', function(data){
var canvas = d3.select('.cell').append("svg");
canvas.selectAll("circles")
.attr("width", 300)
.attr("height", 250)
.data(data)
.enter()
.append("circle")
.attr("cx", function(d){return (+d.x)})
.attr("cy", function(d){return (+d.y)})
.attr("r", function(d){return (+d.radius)})
.attr("fill", "green");
});
I set a code snippet for what it looks like if no svg size specified. So if ur case is like this, the data point at the bottom may be just go out the SVG viewport area.
var canvas = d3.select('.cell').append("svg")
// if u did not specify size
//.attr("width", 400).attr("height", 400);
canvas.selectAll("circle").data([0])
// .attr("width", 300)
// .attr("height", 250)
// .data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return 150;
})
.attr("cy", function(d) {
return 125;
})
.attr("r", function(d) {
return 125;
})
.style("fill", "green");
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</head>
<body>
<div class="cell" style="width:500px; height:500px;"></div>
</body>
</html>
This question has been answered before here: On button click open a new window and draw a large circle with D3
In the solution given by Mark:
http://jsfiddle.net/aj3g5tqg/38/
sampleSVG.append('svg')
.attr('width', 500)
.attr('height', 500) //<-- give the SVG some size
.append("circle")
.style("stroke", "gray")
.style("fill", "red")
.attr("r", 200)
.attr("cx", 250)
.attr("cy", 250)
...
I'm not able to understand how to append multiple circles to the same svg, say in a for loop.
How to do that? Thanks in advance!
Just extend the part that appends a single circle to append inside of the loop. Cast the result of the first svg append to a variable, then iterate and append to it:
var mySVG = sampleSVG.append('svg')
.attr('width', 500)
.attr('height', 500); //<-- give the SVG some size
for (var i=0; i < 250; i = i+10){
mySVG.append("circle")
.style("stroke", "gray")
.style("fill", "red")
.attr("r", 200)
.attr("cx", i)
.attr("cy", i)
}
I have tried a code but it dosent work properly. Can you suggest a method to resolve the error. I am new to Visualization and at the beginning stage of d3.js
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"> </script>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
var sampleSVG = d3.select("#viz")
.append("svg")
.attr("width", 100)
.attr("height", 100);
sampleSVG.append("circle")
.style("stroke", "gray")
.style("fill", "white")
.attr("r", 40)
.attr("cx", 50)
.attr("cy", 50)
.on("mouseover", function() {d3.select(this).append("text").attr("fill","blue").text("fill aliceblue");})
</script>
</body>
</html>
Your are trying to append the text element to the circle, which is not possible.
Create a group element and add your circle and text elements to that group.
Here is an example.
var sampleSVG = d3.select("#viz")
.append("svg")
.attr("width", 100)
.attr("height", 100);
var grp = sampleSVG.append("g");
var circle = grp.append("circle")
.style("stroke", "gray")
.style("fill", "white")
.attr("r", 40)
.attr("cx", 50)
.attr("cy", 50);
circle.on("mouseover", function() {
grp.append("text")
.style("fill", "black")
.attr("x", 32)
.attr("y", 52)
.text("Hello");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="viz"></div>
As suggested here: https://stackoverflow.com/a/16780756/1023562
Create a tooltip div and attach it to mouseover, mousemove and mouseout events.
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
sampleSVG.append("circle")
.style("stroke", "gray")
.style("fill", "white")
.attr("r", 40)
.attr("cx", 50)
.attr("cy", 50)
.on("mouseover", function(){return tooltip.style("visibility", "visible");})
.on("mousemove", function(){return tooltip.style("top",
(d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
Working fiddle: https://jsfiddle.net/vc95wcvm/
Note that in this Fiddle I have loaded http://d3js.org/d3.v2.js in the script panel (because Fiddle refuses to load it over http, it requires https), so the code that interests you is at the bottom of script panel.