Expand d3 map (not individual feature) to use entire svg area - d3.js

I have map data for all of the towns in a state -- let's say California. I display every single town on a map using d3 -- everything is good so far. The projection I use makes use of the scale() and translate() functions, among others, to show my map how I want -- it looks nice.
Here is my problem. I need an automated way to expand my map projection so that it uses the entire svg area. In other words, I want to make my map bigger and bigger until either its width exactly equals the svg width or its height exactly equals the svg height.
I know the bounds function helps do this for an individual feature, but I want the entire state, not the individual town features, to fill the svg area.
Thank you for your help!

Related

Hierarchical axis with ordinal scale

I would like to know, if there is existing code or best practices to realize ordinal axis with a certain hierarchy. Perhaps a example shows, what I mean. I try to realize a Business Support Map like shown in the following image (the upper part, without the legend):
In essence this is a X-Y matrix with cells. The cell coordinates (Acquisition, Headquater, etc.) define the parent layer of the hierarchy. Within each cell there is child ordinal hierarchy of the cell elements. Later on pan and zoom, as well as the addition of layers, which show KPIs, indicators and aggregated data should be easy.
What is here a good combination of scale and axis? Is it easier to build a custom layout?

Add and remove data when panning bar chart in D3

I have a large dataset in an array which translates into about a million 6-pixel wide bars,
Given that about 130 bars fit into 800 pixels of screen, I need to only display a portion of the data at a time. Then, when the user pans the chart, new data will be added and non-visible data will be removed. The user could pan right or left so data need to be able to enter and exit from both sides of the chart.
I feel like the solution involves D3's enter and exit, but I'm unsure how to implement it.
One idea I've had is to use Array.prototype.concat and redraw on pan. Another idea would be to use Array.prototype.slice. I hope those are fast enough.
Any examples?
There are no examples that I'm aware of. Roughly, you would need to do the following.
Draw the initial bar chart. Pass in only the data you'll display (i.e. the first 130 data points if your screen is 800px wide).
On pan, get the translation for the pan. The x translation corresponds to a certain number of bars. Take off this many data points from the beginning of your data array and add that many to the end.
Pass that new data array to D3 and redraw. This tutorial should give you some pointers. Remember to pass a key function to .data() so it knows how to match data to DOM elements.
Similar thing on subsequent pans. Figure out how many bars have been panned and modify the data array accordingly (e.g. using slice and concat -- doesn't matter that much). Redraw the bars.
The concept is very similar to what's done in the tutorial I've linked to, except that the redraw isn't triggered by a timer, but by the pan event.
There are fundamentally two ways to do this. One is that you draw all 1M bars using svg and rely on svg's built in panning. The other is that you draw 130 bars and redraw each time the user pans. enter() and exit() are useful for doing things to data elements in your set that are entering or exiting the scene since the last time it rendered. (d3 determines which elements are
"new" by calling a predicate function on each element. The function has a default but can be user supplied.) You don't actually have to use them here unless you want to be fancy. You can just selectAll the rects from last draw, and .data() them with your new data, and supply the usual calls for drawing rects.

Adding labels to D3 generated circles

I just started learning d3, and very first thing I made is this sorta lame fiddle
Now I wonder how should I attach labels to those circles. Is it possible to nest a label (let's say current radius value) in a circle so it would always move with the circle, or you have to treat labels like independent objects and manage everything accordingly?
You can use a grouping element (<g>) to hold both the circle and the associated text label so they are always together. Then you can position the enter group by using the translate command on the transform attribute (instead of positioning the circle directly as you're doing now).
So basically, you bind the data to the <g> elements instead of to the <circle> elements as you're doing now. Then you can just append a "circle" and a "text" to the "g" (no data join) and both of those child elements will automatically inherit the data themselves.

Readable labels for D3 streamgraph

I'm trying to apply readable labels to a D3 Streamgraph that is rendered using completely dynamic data - various different datasets that are evolving over time from live data and the controls offered to manipulate what is shown too. All this works well - the problem is how to clearly label the streams - short of using a legend.
The great variation of hues and luminance needed makes choosing readable styling for labels that float over the graph extremely tricky, particularly with the limited SVG styling available cross platform and that the labels will inevitably overlap on the background sometimes too. For instance black coloured labels 'work' but it's hard to read sometimes over the top of darker colours (which we really need to ensure a good range)...
Anyone done anything similar/addressed same challenge? I'm currently pondering using a legend instead.
A couple of ideas may help:
Add a background rectangle around the text with opacity set to 0.7 (the color being the same as the data series). This helps make the text pop. For the border of the rectangle, use d3js rgb.darker or rbg.brighter.
var pathStroke = d3.rgb( item.color ).darker(1.4).toString()
For preventing overlapping labels, I can think of two solutions - both hard. Use d3js Force Layout or write your own layout code. We ended up writing our own layout code for tooltips in d3-traits. See tooltips.js and layout.js.
d3.trait.layout.verticalAnchorLeftRight( foci, self.chartRect())
layout.js does have some general purpose and very flexible layout routines. It will layout rectangles within a bounding box avoiding overlap and determines if the labels need to be left or right justified. If the origins of the rects are toward the right edge of the bounding box, they are right justified.

How to custom the map controller in Windows Phone to use my Map image

I am developing a Map App for our school. Our school provide me its own map image and coordinate information. So I want use my map image as the source of map and accord to user's location to show a point in the map image. Can anybody gives me some advice?
Thanks in advance.
There are 2 ways:
It is possible to change the source of the map-tiles (e.g. from Bing to say Nokia or Google) of the Map Control. However, for this to work, it is important that map-tiles source implements mechanisms like quadkeys (e.g. see this). Therefore, to answer your question if you would like to use the Bing Map Control with your school's map so that you can leverage the positioning features of the control, it would require that you have a map-tile server properly designed in order to achieve this. AND, there might be some legal issue with altering the Bing Map control if i am not mistaken.
However, given that you are suggesting an image of the map and then doing positioning, then i would suggest that it can be as easy as you calibrating the pixel X-Y coordinate system on the map with that of the geo-coordinate provided by the geo-watcher. Then, in your code you could do a simple mapping between these 2 systems and then draw something on top of the image. For this part you could use a writeablebitmap or simply use the fact that you can overlay UI controls with silverlight. So, for the latter have a canvas with the an image of the map of your school and then on top of that canvas you can have an <image> representing the device and change its top-left coordinate wrt to the canvas.
So, in summary, as the geo-watcher gives geo x-y coordinates to your code, there is mapping function to the pixel X-Y (which you have pre-calculated) and use that XY to position an overlay <image> or draw some "pin" on a writeablebitmap where you have previously draw the image of the map of your school. Things get complicated with this approach when you want to have zooming as well but, this solution is easily scalable.
Does this help clear things a bit?
Answering 2nd question in comment below:
Yes you can zoom in and out of the canvas but, you would have to program it yourself. The control itself, the canvas does not have this capability. Hence, you would have to recognize the triggers for a zoom action (e.g. clicking on the (+) or (-) buttons or, pinch and stretch gestures) and react to that by re-drawing on the canvas a portion of the region on the canvas so that now that regions stretches over the entire canvas. That is, zooming. For instance for the zoom in case: you would have to determine a geometrical area which corresponds to the zoom factor and is in ratio to the dimensions of the canvas object. Then, you would have to scale that portion up so that edges and empty spaces representing walls and spaces between them grow proportionately. Also, you have to determine the center point of that region which your fix on the canvas so that everything grows away from it. Hence, you would be achieving a appropriate zooming effect. At this point you would have to re-adjust your mapping function of geo-coordinates to pixel XY so that the "pin" or object of interest can be drawn with precision and accurately on the newly rendered surface.
I understand that this can appear quite intensive but, it is straightforward once you appreciate for yourself the mechanics of what is required.
Another easier option could be to use SVG (Scalable Vector Graphics) in a Web-Browser control. Note that you would still require the geo-coordinate to pixel-xy system. However, with this approach you can get the zooming for free with the combination of SVG (which have transformation capabilities for the scale up and down operations) and Web-Browser which enables you to render the SVG and does the gesture handling of zooming in to the map. For that, i believe that the cost of work would be in re-creating the map of your school which is in bitmap to SVG. There are tools like Inkscape which you can use to load the image of your map and then trace the outlines over it. You can then save that outline document as an SVG. In fact, i would recommend this approach to your problem before tackling the Canvas method as i feel that it would be the easiest path for your needs.

Resources