markmarkoh / datamaps

Customizable SVG map visualizations for the web in a single Javascript file using D3.js
http://datamaps.github.io
MIT License
3.78k stars 1.01k forks source link

Bubble Settings #10

Closed designsbybrandon closed 10 years ago

designsbybrandon commented 11 years ago

A second issue / question -- if using bubbles to mark locations, is there a way to offset if 2 markers occupy the same space (example; a company has different divisions each represented by a different color marker, but more than 1 division serves the same city. Currently the last one in the backbone collection is on top and the other is not seen.)

I would like to take out the possibility of user error in overlooking multiple locations and having to adjust LONG/LAT coordinates to display both.

markmarkoh commented 11 years ago

There isn't a way to do that currently, but how would you expect it to work? Like Google Analytics where they show a big bubble, and then when you click you zoom and see the smaller bubbles?

Offsetting currently needs to be done by adjusting the LONG/LAT, which isn't ideal. I'm curious to see some examples of how it should work, though.

designsbybrandon commented 11 years ago

Something I had came across the other day when looking at mapping solution options, was a method to alter a map created with the d3 solution to combine like Google does. http://vis4.net/blog/posts/clean-your-symbol-maps/

That would be 1 option which would probably be best for most. I think for what I am trying to accomplish would need something more similar to an adjustment to the LONG/LAT to put the bubbles close to each other, but not on top of one another. Maybe something similar to the first step of the link (" Finding intersecting symbols") but instead of merging them in step 2, setting a +/- offset to the Long/Lat to slightly move the bubble. Since I am dealing with actual locations and not statistical data as in the example, merging the bubbles wouldn't exactly accomplish the desired affect.

markmarkoh commented 11 years ago

The opacity is a nice trick, you can set the opacity of datamaps bubbles, but yeah, it doesn't work in every situation.

Merging is another workable option, but it adds a few layers of complexity. For instance, now you have to zoom and provide some generic logic for merging.

Opacity + LONG/LAT offset seems like the decent 80% solution. Merging/zooming the 20% solution.

PatriciaW43 commented 10 years ago

I am making a variation of the bombs datamap and I would like to add a label to the bubbles instead of the popups. Is that possible?

markmarkoh commented 10 years ago

Yes! I wrote up a custom plugin for you that puts a label inside the circle. It's working but not totally pretty, so I'll leave it to you to finish. This isn't part of the core library itself, it just uses the Datamap's plugin system.

Checkout it out: http://jsbin.com/ociMiJu/1/edit?html,output

It's at the bottom.

Repeating here:

         //standard plugin interface. Function takes 3 params - a layer ('<g>', data, and the options object)
          function handleBombLabels ( layer, data, options ) {
            var self = this;
            options = options || {};

            d3.selectAll(".datamaps-bubble")
            .attr("data-foo", function(datum) {
             //convert lat/lng into x/y
              var coords = self.latLngToXY(datum.latitude, datum.longitude)

              layer.append("text")
              .attr("x", coords[0] - 10) //this could use a little massaging
              .attr("y", coords[1])
              .style("font-size", (options.fontSize || 10) + 'px')
              .style("font-family", options.fontFamily || "Verdana")
              .style("fill", options.labelColor || "#000")
              .text( datum[options.labelKey || 'fillKey']);
              return "bar";
            });
          }

         //register the plugin to datamaps
          d.addPlugin('bombLabels', handleBombLabels);

         //call the plugin. The 2nd param is options and it will be sent as `options` to the plugin function.
         //Feel free to add to these options, change them, etc
          d.bombLabels(bombs, {labelColor: '#FFF', labelKey: 'fillKey'});