stamen / chartographer

https://stamen.github.io/chartographer/
MIT License
19 stars 4 forks source link

Add typography chart #18

Closed ebrelsford closed 2 years ago

ebrelsford commented 2 years ago

Closes #1.

This is a little rough but it may be good enough for now for this tool. This PR adds a new type of chart, the typography chart, which shows what fonts/symbols look like at a sample of zoom levels. Due to the difficulty of getting the correct fonts out of SDF and into an SVG, I decided to use Mapbox GL here to render the fonts. The nice thing about this is they look very accurate, but the drawback is that it would be more difficult to move this chart into another tool such as Figma. Open to ideas there!

To test:

kelsey-taylor commented 2 years ago

Driving by to take a look at this! 🚗

I'm noticing that I don't see zoom level indicators for typography which I believe I saw during your demo of this in the shareshare

@aparlato I see them on my end in Chrome 🐛 I wonder what's going on there?

I want to think about how we might improve the output of this chart re: long layer names. Perhaps using the text-field property and including the layer name in the tooltip or just on hover?

To echo @aparlato above, there are some quirks when using expressions. These India shields use a match expression to render one of three shields depending on the route type. All that renders in the chart right now is the fallback. This isn't blocking per se, but I wonder if it's possible to just render all possible icons in a case like this:

Screen Shot 2022-02-10 at 3 22 24 PM

One other thought (not blocking, but maybe worth considering as a follow up) is to include some type of horizontal line similar to the mockups to help easily track a single layer across zoom levels. I used a 25% opaque line that reflects the primary color of that layer, for example.

Screen Shot 2022-02-10 at 3 26 23 PM

Everything else looks great visually, though! 🎉 So impressed by how nicely this came together ⭐

ebrelsford commented 2 years ago

Perhaps using the text-field property and including the layer name in the tooltip or just on hover?

I can try that!

One other thought (not blocking, but maybe worth considering as a follow up) is to include some type of horizontal line similar to the mockups to help easily track a single layer across zoom levels.

I can try that too. I know it's hard to do in general but I was hoping we might better see how the fonts will appear on the map by using the map background. Obviously there'll be a ton of overlap with other features (not just the background) so maybe it's not worth it. Definitely looks nicer the way you put it together.

ebrelsford commented 2 years ago

I'd say this is in a much better spot now, thanks for all the feedback @kelsey-taylor @aparlato! Want to take one more look?

Big changes:

Some examples below.

Here you can see the city labels, here hovering over the case where capital == 2:

image

Building details split out by class:

image

kelsey-taylor commented 2 years ago

This is looking so good @ebrelsford! 😍 Already seeing so much cleanup we could do 🙂

Two questions for you:

  1. I'm assuming the blank row here is rendering the fallback? (In this layer, the fallback value is "", which is admittedly not the cleanest way to write this expression)
Screen Shot 2022-02-15 at 10 46 34 AM
  1. Do we need to render fallbacks in all cases? These shields are meant to match the text color with the shield color based on a value in the data, so several of these options would never appear on the map. There aren't fallbacks for the text-color or icon-image in any of these cases:
Screen Shot 2022-02-15 at 10 49 41 AM
ebrelsford commented 2 years ago

Thanks @kelsey-taylor!

1. I'm assuming the blank row here is rendering the fallback? (In this layer, the fallback value is `""`, which is admittedly not the cleanest way to write this expression)

Yes that's what's happening here. These features' icon-image are ['get', 'class'], and I'm not sure what exactly we should do about this in the general case since we aren't loading the vector tiles and don't know that the values of class will be. Maybe we use a ? or some stand-in with a note saying we aren't sure?

2. Do we need to render fallbacks in all cases? These shields are meant to match the text color with the shield color based on a value in the data, so several of these options would never appear on the map. There aren't fallbacks for the `text-color` or `icon-image` in any of these cases:

I'm open to not showing fallbacks if we can determine that they will not appear or are duplicates. The issue is determining when the fallback should not be included. In shields_au, one of the layers in the screenshot, I see:

    "text-color": [
      "match",
      ["get", "network"],
      ["T", "AU:T", "S", "AU:S"],
      "hsl(0, 0%, 100%)",
      ["NR", "AU:NR"],
      "hsl(0, 0%, 0%)",
      ["MR", "AU:MR"],
      "hsl(212, 76%, 46%)",
      "hsl(39, 100%, 78%)"
    ],

So wouldn't hsl(39, 100%, 78%) be the fallback? Or am I misunderstanding?

I could possibly see us saying that if the fallback style is exactly the same as another path (in the case or match expression) then don't bother showing the fallback on the chart. In this case, we could do that if the style was like this instead:

    "text-color": [
      "match",
      ["get", "network"],
      ["T", "AU:T", "S", "AU:S"],
      "hsl(0, 0%, 100%)",
      ["NR", "AU:NR"],
      "hsl(0, 0%, 0%)",
      ["MR", "AU:MR"],
      "hsl(212, 76%, 46%)",
      "hsl(212, 76%, 46%)" /* fallback == other color, won't be rendered on the chart */
    ],

Do you think something like that could work, or am I misunderstanding?

kelsey-taylor commented 2 years ago

So wouldn't hsl(39, 100%, 78%) be the fallback? Or am I misunderstanding?

@ebrelsford to clarify here - each one of the colors in that layer will render with only one of the shield icons, but not all of them. In the screenshot, we're seeing every combination of these two expressions (i.e. a single shield rendering with every color).

ebrelsford commented 2 years ago

@kelsey-taylor With my latest pushes I think this is in a better place with what you're referring to. We now only display case and match variations that should be internally consistent. That is, if a match applies to network == ["NR", "AU:NR"] we should only pair that match with compatible conditions on other properties (such as network == ["NR", "AU:NR"] or network == ["NR"]). This also takes some steps toward making the hover tooltips a little more legible.

image

How does that feel?