different animation for the same event - javascript

The basic idea is that every time that I click the plane will drop a bomb. The moving plane and the dropping bomb are ok, i have two problems:
1) If I drop multiple bombs every explosion animation starts at the same moment of the previous one. Is there is a way to have a different animation for every dropped bomb?
2) I am trying to use ease("cubic"), but there is some mistake using it so if possible can you share a tip on how to use it well?
let svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
speed = 0.3,
movement = 600;
let x = 0;
let y = 50;
let w = 100;
let plane = svg.append("svg:image")
.attr("x", x)
.attr("y", y)
.attr("width", 100)
.attr("height", 100)
.attr("xlink:href", "b52js.png");
transition();
svg.on("click", function() {
var bombingx = plane.attr("x")
let bomb = svg.append("svg:image")
.attr("x", bombingx - 2.5 + 50)
.attr("y", y + 50)
.attr("width", 15)
.attr("height", 20)
.attr("xlink:href", "bomb.png");
bomb
.transition()
.duration(1200)
.attr("y", height - 10)
.ease("cubic")
.on("end", function() {
let exp = svg.append("svg:image")
.attr("x", bombingx)
.attr("y", height - 190)
.attr("height", 250)
.attr("width", 150)
.attr("xlink:href", "giphy.gif");
d3.timer(function(elapsed) {
exp.remove()
}, 1500);
bomb.remove();
})
});

Referring to my comment, lets change the xlink:href randomly on every click. Gifs of the same dimensions and short length are preferred. Or just create multiple copies of the same gif and put them in the array.
Here's a fiddle:
let svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
speed = 0.3,
movement = 600;
let x = 0;
let y = 50;
let w = 100;
let g = svg.append('g').attr('id', 'gg')
let plane = svg.append("svg:image")
.attr("x", x)
.attr("y", y)
.attr("width", 100)
.attr("height", 100)
.attr("xlink:href", "https://pngimg.com/uploads/plane/plane_PNG5243.png");
/* transition(); */
svg.on("click", function() {
var bombingx = plane.attr("x")
let bomb = svg.append("svg:image")
.attr("x", bombingx - 2.5 + 50)
.attr("y", y + 50)
.attr("width", 15)
.attr("height", 20)
.attr("xlink:href", "https://pngimg.com/uploads/bomb/bomb_PNG38.png");
bomb
.transition()
.duration(1200)
.attr("y", height - 10)
.ease("cubic")
.each("end", function() {
let exp = g.append("g:image")
.attr("x", bombingx)
.attr("y", height - 190)
.attr("height", 250)
.attr("width", 150)
.attr("xlink:href", function() {
// Lets create an array of gif links
let gifs = ["https://media.giphy.com/media/xA6evoIAtqSzK/giphy.gif", "https://media.giphy.com/media/rkkMc8ahub04w/giphy.gif", "https://media.giphy.com/media/oe33xf3B50fsc/giphy.gif"]
// A function to return random integers
function randInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
//randInt(3) will return 0,1 or 2.
//This number should be the number of gif links you have in your gif link array.
return gifs[randInt(3)];
});
setTimeout(function() {
exp.remove();
}, 1500);
bomb.remove();
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
<svg width='300' height='300'></svg>

Related

Adjusting circle size text and svg size

I am a new javascript programmer. I'm trying to adjust the circles' size and svg size given the size of the window. Also, the code now creates circles of different sizes, but haven't been able to simultaneously adjust to the text size.
var width = 600;
var height = 600;
// Place your JSON here.
var data = [
{ CategoryName: 'Adaptive Security', SkillProficiencyId: 1 },
{ CategoryName: 'Programmer', SkillProficiencyId: 2 },
{ CategoryName: 'Coffee Drinker', SkillProficiencyId: 3 }
];
/*
This 'cxBase' will be multiplied by element's index, and sum with offset.
So for 3 elements, cx = 0, 200, 400 ...
All these values changeable by this vars.
*/
const cxBase = 200;
const cxOffset = 100;
console.log(data);
// Make SVG container
var svgContainer = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
// This function will iterate your data
data.map(function(props, index) {
var cx = cxBase * (index) + cxOffset; // Here CX is calculated
var elem = svgContainer.selectAll("div").data(data);
var elemEnter = elem.enter()
.append("g")
var circles = elemEnter.append("circle")
.attr("cx", cx)
.attr("cy", 100)
.attr("r", props.SkillProficiencyId * 20)
.style("fill", "blue");
elemEnter
.append("text")
.style("fill", "white")
.attr("dy", function(d){
return 105;
})
.attr("dx",function(d){
return cx - (props.CategoryName.length * 3.5);
})
.text(function (d) {
return props.CategoryName
});
});
Using .attr("viewBox", "0 0 680 490") doesn't work so far. Just makes all the circles bigger but not in proportion to the window
// Make SVG container
var svgContainer = d3.select("body")
.append("svg")
.attr("viewBox", "0 0 680 490")
.attr("presserveAspectRatio", "xMinYMin meet")
//.attr("height", height)
;
I made five improvements:
Circle's width based on SkillProficiencyId.
Increased the svg width from 600 to 900.
Text will appear always on the middle of the circle: text.style("text-anchor", "middle") did the trick.
Text size proportional to circle size;
A smartest way to calc circle dx (w/o using arbritary offsets);
Codepen: https://codepen.io/mayconmesquita/pen/RwWoZbv
JS Code:
var width = 900;
var height = 400;
// Place your JSON here.
var data = [
{ CategoryName: 'Adaptive Security', SkillProficiencyId: 1 },
{ CategoryName: 'Programmer', SkillProficiencyId: 2 },
{ CategoryName: 'Coffee Lover', SkillProficiencyId: 3 },
{ CategoryName: 'Coffee Roaster', SkillProficiencyId: 4 }
];
function getCircleSize(SkillProficiencyId) {
var minSize = 60;
return minSize + (minSize * (SkillProficiencyId * .2));
}
// Make SVG container
var svgContainer = d3
.select("body")
.classed("svg-container", true)
.append("svg")
.attr("width", width)
.attr("height", height);
// This function will iterate your data
data.map(function(props, index) {
/*
The new CX calc:
('circleSize' * 2) will be multiplied by element's index.
So for 3 elements, cx = 70, 140, 210 ...
All these values changeable by this vars.
*/
var circleSize = getCircleSize(props.SkillProficiencyId);
var cx = (circleSize * 2) * (index); // Here CX is calculated
var elem = svgContainer.selectAll("div").data(data);
var elemEnter = elem
.enter()
.append("g")
.attr("transform", "translate(100, 0)"); // prevent svg crops first circle
var circles = elemEnter
.append("circle")
.attr("cx", cx)
.attr("cy", 160)
.attr("r", circleSize)
.style("fill", "blue");
elemEnter
.append("text")
.style("fill", "white")
.attr("dy", 165)
.attr("dx", cx)
.text(props.CategoryName)
.style("font-size", ((circleSize * .2) + index) + "px")
.style("text-anchor", "middle");
});

Using keydown event with d3.drag () to rotate a SVG

I have a SVG and I want to apply rotation transformation on it but not just with the mouse drag, instead with a mouse drag while pressing the alt key. I have tried to implement something but things donot seem to work as I want. Below is what i have implemented. How can I get the SVG rotated on dragging the mouse while pressing the alt key?
var width = 590, height = 400;
var svg = d3.select("#sketch4").append("svg")
.attr("width", width)
.attr("height", height)
//.call(d3.zoom().on("zoom", zoomed))
.call(d3.drag().on('drag', dragged))
.append("g")
var rect = svg.append("rect")
.attr("x", 100)
.attr("y", 100)
.attr("width", 60)
.attr("height", 30)
.attr("fill", "green")
function dragged() {
if (d3.event.sourceEvent.altKey){
var me = sketchSVG.node()
var x1 = me.getBBox().x + me.getBBox().width/2;
var y1 = me.getBBox().y + me.getBBox().height/2;
sketchSVG.attr("transform","rotate("+d3.event.y+","+x1+","+y1+")" );
metricSVG.attr("transform","rotate("+d3.event.y+","+x1+","+y1+")" );
}
};
You need to use d3.event.sourceEvent.x and d3.event.sourceEvent.y. Changing that should get your code working.
To move/zoom your element, create and else condition and just use sketchSVG.attr("transform",d3.event.transform) for zooming and translating the element.
var width = 590,
height = 400;
var svg = d3.select("#sketch4").append("svg")
.attr("width", width)
.attr('id', 'sketchSvg')
.attr("height", height)
.append("g")
d3.select('#sketchSvg')
.call(d3.zoom().on("zoom", dragged))
var rect = svg.append("rect")
.attr("x", 100)
.attr("y", 100)
.attr("width", 60)
.attr("height", 30)
.attr("fill", "green")
function dragged(d) {
if (d3.event.sourceEvent.altKey && d3.event.sourceEvent.type == 'mousemove') {
var me = svg.node()
var x1 = me.getBBox().x + me.getBBox().width / 2;
var y1 = me.getBBox().y + me.getBBox().height / 2;
svg.attr("transform", "rotate(" + d3.event.sourceEvent.y + "," + x1 + "," + y1 + ")");
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id='sketch4'></div>
Here's one on JSFiddle

Inserting data (bar charts and weather info) into SVG Circles

I'm trying to create a visual effect (using D3.js and json) where 4 small circles will pop up once I click on the big yellow circle. I want to make sure that ALL of the circles will present pieces of information that I'm trying to assign to each and every one of them. I plan to have:
-The 1st big yellow circle to present the weather (sunny, mostly cloudy, etc)
-2 small circles to present weather info by word
-2 small circles present a D3 bar chart that I made, along with some weather info by word
(I have all of the info separated by spaces and comments)
However, my problem is (for the lack of a better explanation) that I am just stumped! I have no idea how to make that happen. I would really appreciate it if I can get help from you guys. Here's my code (HTML and JS):
var h = 2000;
var w = 2000;
var xGrid = 300;
var yGrid = 300;
var radius = 300;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var shape = svg.append("circle")
.attr("cx", xGrid)
.attr("cy", yGrid)
.attr("r", radius)
.style("fill", "yellow");
shape.on("click", function(){
var circle1 = svg.append("circle")
//.attr("cx", (xGrid-radius/2)+0)
//.attr("cy", (yGrid-radius/2)+0)
.attr("cx", xGrid - radius/2)
.attr("cy", yGrid - radius/2)
.attr("r", radius/2)
.style("fill", "red");
var circle2 = svg.append("circle")
//.attr("cx", (xGrid-radius/2)+10)
//.attr("cy", (yGrid-radius/2)+10)
.attr("cx", xGrid + radius/2)
.attr("cy", yGrid - radius/2)
.attr("r", radius/2)
.style("fill", "blue");
var circle3 = svg.append("circle")
// .attr("cx", (xGrid-radius/2)+20)
// .attr("cy", (yGrid-radius/2)+20)
.attr("cx", xGrid - radius/2)
.attr("cy", yGrid + radius/2)
.attr("r", radius/2)
.style("fill", "green");
var circle4 = svg.append("circle")
// .attr("cx", (xGrid-radius/2)+30)
//.attr("cy", (yGrid-radius/2)+30)
.attr("cx", xGrid + radius/2)
.attr("cy", yGrid + radius/2)
.attr("r", radius/2)
.style("fill", "purple");
});
<!-- ///////////////////////////////////////////////////////////////////////////// /////////////////
///////////////////////////////(END) Circle Pop-up (END)/////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////-->
</script>
<!--///////////////////////////////////////////////////////////////////////////// ////////////////////////
///////////////////////////(START) Info for circles to present (START)////////////////////////////////
///////////////////////////////////////////////////////////////////////////// //////////////////////////////-->
<!--/////Main Circle display/////////-->
<p id="w"></p><p id="main"></p>
<!--//////Circle 1 (upper left corner) display///////////-->
<p id="rh"></p><p id="c1a"></p>
<!--///////Circle 2 (upper right corner) display//////////-->
<p id="ws"></p><p id="c2a"></p>
<p id="wd"></p><p id="c2b"></p>
<p id="we"></p><p id="c2c"></p>
<p id="wm"></p><p id="c2d"></p>
<!--////////Circle 3 (lower left corner) display/////////-->
<p id="pti"></p><p id="c3a"></p>
<p id="ptc"></p><p id="c3b"></p>
<p id="df"></p><p id="c3c"></p>
<p id="dc"></p><p id="c3d"></p>
<!--///////Circle 4 (lower right corner) display//////////-->
<p id="hif"></p><p id="c4a"></p>
<p id="hic"></p><p id="c4b"></p>
<p id="sr"></p><p id="c4c"></p>
<p id="uv"></p><p id="c4d"></p>
<script type = "text/javascript">
var dataForMainCircle = '{"weather": "Mostly Cloudy"}';
var mcDis= JSON.parse(dataForMainCircle);
var weather = "weather: ";
document.getElementById("w").innerHTML = weather;
document.getElementById("main").innerHTML = mcDis.weather;
/////////////////////////////////////////////////////////////////////////////////
////////////Setup for display of 1st circle info///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
var dataForCircle1b = '{"relative_humidity": "92%"}';
var relativeHum = "Relative Humidity: ";
var c1Dis = JSON.parse(dataForCircle1b);
d3.json("js/tempGraph.json", function (data) {
var canvas = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) {return d.temp * 10; })
.attr("height", 48)
.attr("y", function (d,i) {return i * 50; })
.attr("fill", "red");
canvas.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("fill", "white")
.attr("y", function (d,i) {return i * 50 + 24; })
.text(function (d) {return d.temp; })
})
document.getElementById("rh").innerHTML = relativeHum;
document.getElementById("c1a").innerHTML = c1Dis.relative_humidity;
/////////////////////////////////////////////////////////////////////////////////////////
/ ////////////////////Setup for display of 2nd circle info////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
var dataForCircle2 = '{"wind_string": "Calm", "wind_dir": "SW", "wind_degrees": 229, "wind_mph": 2}';
var c2Dis = JSON.parse(dataForCircle2);
var windCon = "Wind Condition: ";
var windDir = "Wind Direction: ";
var windDeg = "Wind Degree: ";
var windMph = "Wind (Miles Per Hour): "
document.getElementById("ws").innerHTML = windCon;
document.getElementById("c2a").innerHTML = c2Dis.wind_string;
document.getElementById("wd").innerHTML = windDir;
document.getElementById("c2b").innerHTML = c2Dis.wind_dir;
document.getElementById("we").innerHTML = windDeg;
document.getElementById("c2c").innerHTML = c2Dis.wind_degrees;
document.getElementById("wm").innerHTML = windMph;
document.getElementById("c2d").innerHTML = c2Dis.wind_mph;
///////////////////////////////////////////////////////////////////////////// //////////////////////////////////
//Setup for display of 3rd circle info/////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////
var dataForCircle3 = '{"precip_today_in": "0.00", "precip_today_metric": "0"}';
var c3Dis = JSON.parse(dataForCircle3);
var predate = "Today's Precipitation: ";
var prem = "Precipitation Metric: ";
//var dewF = "Dewpoint-F: ";
//var dewC = "Dewpoint-C: ";
document.getElementById("pti").innerHTML = predate;
document.getElementById("c3a").innerHTML = c3Dis.precip_today_in;
document.getElementById("ptc").innerHTML = prem;
document.getElementById("c3b").innerHTML = c3Dis.precip_today_metric;
//document.getElementById("df").innerHTML = dewF;
//document.getElementById("c3c").innerHTML = c3Dis.dewpoint_f;
d3.json("js/dewGraph.json", function (data) {
var canvas = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) {return d.dewpoint * 10; })
.attr("height", 48)
.attr("y", function (d,i) {return i * 50; })
.attr("fill", "white");
canvas.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("fill", "white")
.attr("y", function (d,i) {return i * 50 + 24; })
.text(function (d) {return d.dewpoint; })
})
//document.getElementById("dc").innerHTML = dewC;
//document.getElementById("c3d").innerHTML = c3Dis.dewpoint_c;
<!--//////////////Setup for display of 4th circle display////////////////////-->
var dataForCircle4 = '{"heat_index_f": "NA", "heat_index_c": "NA", "solarradiation": "--", "UV": "0"}';
var c4Dis = JSON.parse(dataForCircle4);
var heatF = "Heat Index-F: ";
var heatC = "Heat Index-C: ";
var sunR = "Solar Radiation: ";
var ultraV = "UV: ";
document.getElementById("hif").innerHTML = heatF;
document.getElementById("c4a").innerHTML = c4Dis.heat_index_f;
document.getElementById("hic").innerHTML = heatC;
document.getElementById("c4b").innerHTML = c4Dis.heat_index_c;
document.getElementById("sr").innerHTML = sunR;
document.getElementById("c4c").innerHTML = c4Dis.solarradiation;
document.getElementById("uv").innerHTML = ultraV;
document.getElementById("c4d").innerHTML = c4Dis.UV;
d3.json("js/tempGraph.json", function (data) {
var canvas1 = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas1.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) {return d.temp * 10; })
.attr("height", 48)
.attr("y", function (d,i) {return i * 50; })
.attr("fill", "red");
canvas1.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("fill", "white")
.attr("y", function (d,i) {return i * 50 + 24; })
.text(function (d) {return d.temp; })
})
d3.json("js/dewGraph.json", function (data) {
var canvas2 = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas2.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) {return d.dewpoint * 10; })
.attr("height", 48)
.attr("y", function (d,i) {return i * 50; })
.attr("fill", "blue");
canvas2.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("fill", "white")
.attr("y", function (d,i) {return i * 50 + 24; })
.text(function (d) {return d.dewpoint; })
})
</script>
</body>
</html>
Keep in mind, this program is sort of a prototype. My main concern is getting the info assigned for the circles INSIDE of them. If you guys found any errors/mix-ups in the code, feel free to notify me. Thank you!!
Ok, as promised, an example. It doesn't look super cool, but at least you will get the picture. If you have more questions, please shoot! Here goes:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="donut.js" type="text/javascript"></script>
<style>
body{
background-color:black;
}
#container {
position:relative;
display:inline-block;
width:100%;
}
.row{
position:relative;
display:inline-block;
width:100%;
text-align:center;
}
#chart{
width:60%;
position:relative;
display:inline-block;
}
text{
font-size:1.4em;
}
</style>
</head>
<body>
<div id="container">
<div class="row">
<div id="chart">
</div>
</div>
</div>
<script>
var data = [
{"type":"weather", "status":"sunny"},
{"type":"humidity", "status":"high"},
{"type":"temperature", "status":"23°"},
{"type":"pressure", "status":"1040 hpa"},
{"type":"wind", "status":"East"},
];
var chartWidth = 500;
var chartHeight = 500;
/* Adding the svg drawing canvas by selecting the element that will contain the svg. put it in a var,
as it is a d3 selection. We can reuse this selection. Remember, when chaining, you will get returned the
element you last appended, in this case the svg.
*/
var svg = d3.select("#chart")
.append("svg")
.attr({ // you can put attributes in a javascript object, i like this notation better.
width:chartWidth,
height:chartHeight
});
/* Here I am going to add the circles. With SVG elements, you cannot draw inside other elements. There are only 2 elements
which can contain other elements (as far as I know) and that is the SVG element itself and the g element. So if you want
to give the impression that the elements are inside one another, you need to make them overlap. So if I add a circle and then
add text with coordinates that match the circle, the text will overlap the circle, giving the impression it is inside it.
*/
var circles = svg.selectAll("circle")
.data(data) //binding the data. I want 5 circles for my 5 pieces of data
.enter()
.append("circle")
.attr({
cx:function(d,i){ //when doing the append on a d3 selection, you are iteration over each element!
/* I will use the index (i) to 'identify' the pieces of data and to hardcode their x central point positions */
if(i == 0) {
return chartWidth/2;
}
if(i == 1) {
return chartWidth/5;
}
if(i == 2) {
return chartWidth *(2/7);
}
if(i == 3) {
return chartWidth *(5/7);
}
if(i == 4) {
return chartWidth * (4/5);
}
},
cy:function(d,i){ //when doing the append on a d3 selection, you are iteration over each element!
/* I will use the index (i) to 'identify' the pieces of data and to hardcode their y central point positions */
if(i == 0) {
return chartHeight/2;
}
if(i == 1) {
return chartHeight *(3/5);
}
if(i == 2) {
return chartHeight *(4/5);
}
if(i == 3) {
return chartHeight *(4/5);
}
if(i == 4) {
return chartHeight * (3/5);
}
},
r:function(d,i) { /* the radius is in function of the type. The first one (weather) should be the biggest one */
if(d.type === "weather") {
return 200;
}
else{
return 75;
}
},
fill:"yellow",
stroke:"black"
});
/* Now i'll append the text as last, so it overlaps nicely with the circles. For positioning, i ll have to reuse the x and y functions
from the circles. I want the text to be positioned at the center of the cirkels.
*/
var texts = svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(function(d){ return d.status})
.attr({
x:function(d,i){
/* So I used the same positioning for the text as for the center points of the circles.
you should realize that the text really starts at the middle of the circles. So you
should substract a bit from the x position to get them nicely in the middle. I aint going
for that trouble, its just an example.
*/
if(i == 0) {
return chartWidth/2;
}
if(i == 1) {
return chartWidth/5;
}
if(i == 2) {
return chartWidth *(2/7);
}
if(i == 3) {
return chartWidth *(5/7);
}
if(i == 4) {
return chartWidth * (4/5);
}
},
y:function(d,i){ //when doing the append on a d3 selection, you are iteration over each element!
/* I will use the index (i) to 'identify' the pieces of data and to hardcode their y central point positions */
if(i == 0) {
return chartHeight/2;
}
if(i == 1) {
return chartHeight *(3/5);
}
if(i == 2) {
return chartHeight *(4/5);
}
if(i == 3) {
return chartHeight *(4/5);
}
if(i == 4) {
return chartHeight * (3/5);
}
}
});
</script>
</body>
</html>
I did not add the function to click on the first circle to show the others. I could if you want me to though, but I felt like this example already has enough stuff in it to learn from.

D3.JS add zoom and listitems to rect

I want to achieve followings,
1 - Create a given column matrix with rectangles with provided colours
Done
2 - Make this matrix zoom able
3 - Add list items to each rectangle which will only show numbers of list items in it if completely zoomed out and on zoom in, it will show the list items e.g. there Titles.
Now I want to achieve Number 2 here, this is what I am trying,
http://jsfiddle.net/nhe613kt/25/
When I add code for zooming it fails,
var svgContainer = d3.select("body").append("svg")
.attr("width", 300)
.attr("height", 300)
.style("background-color", "black");
var zoomed = function () {
svgContainer.attr("transform", "translate("+ d3.event.translate + ")
scale(" + d3.event.scale + ")");
};
var zoom = d3.behavior.zoom()
.scaleExtent([1, 8])
.on("zoom", zoomed);
.size([width, height]);
var rectangle1 = svgContainer.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red")
.call(zoom);;
var rectangle2 = svgContainer.append("rect")
.attr("x", 100)
.attr("y", 0)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "yellow");
var rectangle3 = svgContainer.append("rect")
.attr("x", 200)
.attr("y", 0)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red");
var rectangle4 = svgContainer.append("rect")
.attr("x", 0)
.attr("y", 100)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "yellow");
var rectangle5 = svgContainer.append("rect")
.attr("x", 100)
.attr("y", 100)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red");
var rectangle6 = svgContainer.append("rect")
.attr("x", 200)
.attr("y", 100)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "yellow");
var rectangle7 = svgContainer.append("rect")
.attr("x", 0)
.attr("y", 200)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red");
var rectangle8 = svgContainer.append("rect")
.attr("x", 100)
.attr("y", 200)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "yellow");
var rectangle9 = svgContainer.append("rect")
.attr("x", 200)
.attr("y", 200)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red");
My desired result will be this,
http://bl.ocks.org/mbostock/3680957
The code you provided has several problems:
1. There is a syntax error in definition of zoom (.on("zoom", zoomed);)
2. You haven't defined width and height.
3. zoomed function possibly couldn't be parsed because of wrong line breaks (notice point where you define scale of transformation).
Here is JSFiddle, where zoom works correctly for first element of matrix. Main points is:
// don't forget about width and height
var width = 960,
height = 500;
// make sure that string defining transform attribute is correct. scale isn't a method, but part of string
var zoomed = function () {
svgContainer.attr("transform", "translate("+ d3.event.translate + ")scale(" + d3.event.scale + ")");
};
// don't place semicolon after on("zoom", zoomed)
var zoom = d3.behavior.zoom()
.scaleExtent([1, 8])
.on("zoom", zoomed)
.size([width, height]);
// add zoom behaviour to desired rectangle
var rectangle1 = svgContainer.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red")
.call(zoom);

Embedding SVG shapes in a d3.js animation

I created a jsfiddle here. There are a couple of things I need to do.
How do you properly embed svg code (from an existing shape) into a d3.js animation? My svg is popping up twice.
How do you attach that svg to another shape so that the animation happens simultaneously for both shapes?
#slider {
width: 490px;
}
#_rb {
color: #000;
}
5
JavaScript:
var width = 500,
height = 500,
minRadius = 10,
maxRadius = 250,
minHeight = 100,
maxWidth = 500;
var duration = 5000;
d3.select("body").append("input")
.attr("type", "range")
.attr("id", "slider")
.attr("min", 1000)
.attr("max", 10000)
.attr("value", duration)
.on("change", function () {
duration = this.value;
d3.select("#_rb").property("value", d3.round(duration / 1000));
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("circle")
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("r", minRadius)
.style("fill", "steelblue")
.call(transition, minRadius, maxRadius);
svg.append("use")
.attr("xlink:href", "#Layer_1")
.attr("width", width / 2)
.attr("height", height / 2)
.attr("x", 100)
.attr("y", 100)
.call(transition, minHeight, maxWidth);
function transition(element, start, end) {
element.transition()
.duration(duration)
.attr("r", end)
.attr("height", end)
.attr("width", end)
.each("end", function () {
d3.select(this).call(transition, end, start);
});
}

Categories