mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.09k stars 2.21k forks source link

Create a data-driven styling example #2439

Closed lucaswoj closed 8 years ago

lucaswoj commented 8 years ago

Now that we've merged #1932, we should post a simple example using data-driven styling.

We only support data-driven styling for circle-size and circle-color in mapbox-gl-js. There’s no support for other properties, mapbox-gl-native, or Studio. Given all the caveats, we aren’t going to advertise it too heavily yet but I’d love to get some intrepid users using it.

I created a simple example here: https://bl.ocks.org/lucaswoj/4fa16fcf9663f67f6b7d4a7225dc3524

cc @danswick @tristen @peterqliu

peterqliu commented 8 years ago

oof, do we support compound styling by data and zoom? this would apply for any physical encoding, like circle-size, icon-size, text-size, and line-width

lucaswoj commented 8 years ago

Not yet, but that's high on my priority list. Tracking in https://github.com/mapbox/mapbox-gl-js/issues/2428.

BrunoSalerno commented 8 years ago

@lucaswoj are categories (strings) supported? For instance, the following isn't working:

'circle-color': {
          property: 'line',
          stops: [
            ['A', '#8a8acb'],
            ['B', '#223b53'],
            ['C', '#3887be']
          ]
        }
lucaswoj commented 8 years ago

@brunoabinader see https://github.com/mapbox/mapbox-gl-style-spec/pull/445

EDIT: You also need to add type: "categorical"

e-n-f commented 8 years ago

From chat with @peterqliu: I'm going to pull the census race and ethnicity data from this datamaps map into vector tiles to try with this.

peterqliu commented 8 years ago

🙇 thanks @ericfischer. This will come out as a map ID on enf's account; @lucaswoj what's the best way to store this for longevity?

e-n-f commented 8 years ago

Census 2010 race and ethnicity data for a square around San Francisco is in enf.4zdd7xxg now, created with tippecanoe -f -o sf-2010.mbtiles -z12 sf-2010.json from s3://mapbox/playground/ericfischer/sf-2010.json.

e-n-f commented 8 years ago

The other case I'd be really interested to try with this is circle-size for intersection pedestrian volumes. The data is in enf.6fzknzvu and is used in this Classic style.

peterqliu commented 8 years ago

@ericfischer thanks for putting those together. Next actions on me to draft an example

lucaswoj commented 8 years ago

Here's a demo of the pedestrian volume data set!

peterqliu commented 8 years ago

And here's the one for ethnicity: https://jsfiddle.net/8vnsbpqf/5/. The tileset is hosted on examples account; just gotta swap out my token and this should be ready as an example.

peterqliu commented 8 years ago

Also, it's nice that we have an example each for categorical and continuous.

e-n-f commented 8 years ago

Thanks @lucaswoj! It's great to be able to do the pedestrian map with GL now.

BrunoSalerno commented 8 years ago

Excellent @lucaswoj !!!

ryanbaumann commented 8 years ago

How does setPaintProperty(layer, paint-prop, value) work with the new data-driven styles?

map.setPaintProperty(layer, 'circle-radius-stops', [ [1, 1], [2, 5], [3, 10] ])

Throws error

map.js:929 Error: layers.layer.paint.circle-radius-stops: unknown property "circle-radius-stops"(…)

Edit: Got it - we can pass an object to the setPaintProperty function. Awesome work! Quick example:

base_radius = 1
radius_breaks = [0, 3, 6, 9]
radius_values=[1, 2, 5, 10]
circle_radius_style = { "base": base_radius,
                              "stops": [
                                [radius_breaks[0], radius_values[0]],
                                [radius_breaks[1], radius_values[1]],
                                [radius_breaks[2], radius_values[2]],
                                [radius_breaks[3], radius_values[3]]
                               ]
                        };
mapid.setPaintProperty(layer, 'circle-radius', circle_radius_style);
tmcw commented 8 years ago

https://www.mapbox.com/mapbox-gl-js/example/data-driven-circle-colors/ is live

wandergis commented 8 years ago

data-driven styling can't work on line-color,i wrote the code:

"line-color": {
                    property: 'mp_type',
                    type: 'categorical',
                    stops: [
                        ['0x06', '#2C9DF1'],
                        ['0x05', '#223b53'],
                        ['0x03', '#e55e5e'],
                        ['0x08', '#3bb2d0'],
                        ['0x02', '#ccc']
                    ]
                }

but it doesn't work.

lucaswoj commented 8 years ago

@wandergis line-color does not yet support data-driven styling. This feature is coming in a release soon!

josiekre commented 8 years ago

+1 for fill-color working with type: 'categorical'

NM. I see from #2431 that it is implemented already!

jfirebaugh commented 8 years ago

The documentation of individual properties on https://www.mapbox.com/mapbox-gl-style-spec/ (e.g. fill-color) now includes a version support matrix that details support for data-driven styles. We're going to keep this updated as we roll out support for data-driven styling of more properties.

wandergis commented 8 years ago

When can line-color support data-driven styling? That would be very useful.

kdanaher commented 7 years ago

@lucaswoj : Is map.setPainProperty able to tap into the property or stops parameters of fill-color currently or is this planned for a future release by chance?

lucaswoj commented 7 years ago

@kdanaher data-driven styling support is documented in the style spec;

wroscoe commented 7 years ago

It was unclear to me that the values and zoom needed to be in ascending order to work. After this, it worked great.

pzupan commented 7 years ago

I'm unable to get circle-color to work in v0.27.0/mapbox-gl.js. The circle-radius property responds properly in the code below, but not circle-color.

map = new mapboxgl.Map({
      container: 'map', 
      pitch: 0.01,
      style: 'mapbox://styles/mapbox/streets-v9',
      zoom: 1
    });

    map.on('load', function () {   
      map.addSource("points", {
        type: "geojson",
        data: ""
      });
      map.addLayer({
        id: "points",
        type: "circle",
        source: "points",
        paint: {
          "circle-color": { 
            property: "point_position",
            type: "categorical",
            stops: [
              [1, "#1e8449"],
              [2, "#ff5733"],
              [3, "#666666"]
            ]
          },
          "circle-radius": {
            base: 3,
            stops: [[8, 6], [22, 120]]
          },
        }
      });

      map.addLayer({
        id: "pointsLabels",
        type: "symbol",
        source: "points",
        layout: {
          "text-field": "{name}\n{created_at}",
          "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
          "text-offset": [0.6, 0.0],
          "text-anchor": "left",
          "text-size": 11
        }
      });

I've attached a screenshot indicating that the map object has the relevant data "point_position", but the points on the map are not the correct color. screenshot

screenshot 2

And I'm not seeing any errors in the console.