haskellhaskell-diagrams

How to control scale invariance?


I am trying to put several diagrams together in a kind of a table. I think this is called "index print", photography people do that when they have to review many photographs at once. Anyway, this is the code:

main :: IO ()
main = mainWith @(Diagram B)
     $ (tile . fmap renderOne) examples

renderOne :: AnyGraph -> Diagram B
renderOne (AnyGraph gr) = ...

tile :: [Diagram B] -> Diagram B
tile xs = let columns = (ceiling . sqrt . fromIntegral . length) xs
          in (vcat . fmap hcat . List.chunksOf columns) xs

It does not work as I expect. But let us approach it gradually. First, here is a render of a single tile:

one

Now, let us hcat four tiles together.

hcat

Add a second row: (See how scale invariant features thicken.)

tile2

And this is how it looks with 4 rows:

tile

Out of hand!

It seems to me that scale invariant features, such as arrow heads, are scaled in proportion to the area of the picture. But in this case, I need to grow my diagram without re-scaling those features. How can I achieve that?


Solution

  • The user manual section on measurement units is what you want to look at. Things like arrowheads are by default measured in "normalized" units, which are scaled so that they are always a constant proportion of the size of the whole picture. If I understand your use case correctly, I think you probably want to use local units instead. Use the primed variant of whatever arrow function you are using, and give it an options record something like

    (with & headLength .~ local 0.1)
    

    but with whatever number makes your pictures look the way you want. See the arrow tutorial for more on arrow options.