Maps: zoom on a circle

869 views
Skip to first unread message

Bixente

unread,
Jan 31, 2012, 4:46:17 PM1/31/12
to d3-js
Hey,

I am trying to create zoomable maps with cities. I can properly zoom
on countries but everytine I try to insert cities, I also zoom on the
svg:circle I created before. I know I would need to rescale the
circles in question but I still don't know how to do it.

I know I need to rewrite the redraw function but I don't know how to
properly rescale the cities.

d3.json("C18_st.json", function(json) {
countries
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("fill", "black")
.attr("d", path)

;
});

d3.json("cities2.json", function(collection) {
cities
.selectAll("circle")
.data(collection.features
.sort(function(a, b) { return b.properties.percentage -
a.properties.percentage; }))
.enter().append("svg:circle")
.attr("fill", "red")
.attr("r", function(d) { return r(d.properties.percentage)*50; })
.attr("transform",function(d) { return "translate(" +
xy(d.geometry.coordinates) + ")"; } );
}
);


function redraw() {
svg.attr("transform",
"translate(" + d3.event.translate + ")"
+ "scale(" + d3.event.scale + ")")
}


Thanks!

Bixente

*malvenko

unread,
Feb 2, 2012, 1:15:03 AM2/2/12
to d3-js
Hey Bixente,

I'm working on a zoomable scatter plot with circles that grow as you
zoom in.

When the map is zoomed, you can draw the circles multiplying the
radius by the map scale factor every time you draw a circle:

.attr("r", function (d) { return Math.sqrt(5 * (d.volume *
d3.event.scale) / Math.PI); })

Note that d3.event.scale exists once the map is zoomed in or out --
you can use a temporary scale factor of 1 when the graph runs the
first time (when d3.event.scale = undefined)

Hope this helps!!

Bixente

unread,
Feb 12, 2012, 1:43:25 PM2/12/12
to d3-js
Hey,

Thanks for that. If someone knows how to do this very simple thing,
I'd be happy to learn more.

Bixente

On Feb 2, 6:15 am, "*malvenko" <malve...@gmail.com> wrote:
> Hey Bixente,
>
> I'm working on a zoomable scatter plot with circles that grow as you
> zoom in.
>
> When the map is zoomed, you can draw the circles multiplying the
> radius by the map scale factor every time you draw a circle:
>
>  .attr("r", function (d) { return Math.sqrt(5 * (d.volume *d3.event.scale) / Math.PI); })
>
> Note thatd3.event.scaleexists once the map is zoomed in or out --
> you can use a temporary scale factor of 1 when the graph runs the
> first time (whend3.event.scale= undefined)

Jason Davies

unread,
Feb 17, 2012, 1:39:20 PM2/17/12
to d3...@googlegroups.com
On Tue, Jan 31, 2012 at 01:46:17PM -0800, Bixente wrote:
> I am trying to create zoomable maps with cities. I can properly zoom
> on countries but everytine I try to insert cities, I also zoom on the
> svg:circle I created before. I know I would need to rescale the
> circles in question but I still don't know how to do it.

I'm not sure I understand the question. Are you saying you want to keep
the circles a constant size while zooming?

This might be relevant:

http://www.jasondavies.com/poincare-disc/

I used SVG's transform for zooming, while changing the stroke-width to
keep it a constant width at different scales. The code is here:

http://www.jasondavies.com/poincare-disc/poincare-disc.js

Likewise, to keep the circles a constant size you need to invert the
transformation on the radius (and potentially the stroke-width).

--
Jason Davies, http://www.jasondavies.com/

Bixente

unread,
Feb 18, 2012, 10:17:34 AM2/18/12
to d3-js
Hey,

Thanks for that Jason. I just realised that I was focusing on
d3.event.scale when I wasn't even properly selecting my circles. So
the solution was pretty easy.

function redraw() {
svg.attr("transform",
"translate(" + d3.event.translate + ")"
+ "scale(" + d3.event.scale + ")");
cities2.selectAll("circle")
.attr("r", function(d) { return r(d.properties.percentage)*50/
d3.event.scale; })
}

Thanks again,

Bixente
Reply all
Reply to author
Forward
0 new messages