Files
to-hen/onomastics-ng/lib/Onomap/Svg.hs

83 lines
2.9 KiB
Haskell
Raw Normal View History

2022-04-17 21:04:13 +02:00
{-# LANGUAGE OverloadedStrings #-}
2022-04-19 23:11:06 +02:00
module Onomap.Svg (drawMap, renderMap) where
2022-04-17 21:04:13 +02:00
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import Data.Text (Text)
2022-04-19 23:11:06 +02:00
import Data.Text.Lazy (toStrict)
2022-04-17 21:04:13 +02:00
import qualified Data.Text as Text
import Graphics.Svg
import Text.Printf (printf)
2022-04-19 23:11:06 +02:00
import Onomap.Types (Area (..), ByArea (..))
2022-04-17 21:04:13 +02:00
2022-04-19 23:11:06 +02:00
renderMap :: Text -> [Area] -> ByArea Double -> Text
renderMap fillColor areas statistics = toStrict $ prettyText $ drawMap fillColor areas statistics
drawMap :: Text -> [Area] -> ByArea Double -> Element
2022-04-17 21:04:13 +02:00
drawMap fillColor areas statistics =
doctype <> with (svg11_ content) [Version_ <<- "1.1", Width_ <<- "650", Height_ <<- "900"]
where
theMaximum = maximum $ getByArea statistics
localize = Text.replace "." "," . Text.dropWhileEnd (== '.') . Text.dropWhileEnd (== '0')
showRounded = Text.pack . printf "%.2f"
frameColor = "grey"
areaPaths =
foldMap
( \area ->
let count = fromMaybe 0 (Map.lookup (key area) (getByArea statistics))
in path_
[ Stroke_ <<- frameColor
, Fill_ <<- fillColor
, Fill_opacity_ <<- showRounded (if count == 0 then 0 else count / theMaximum)
, D_ <<- path area
]
( title_
[]
( toElement $
name area <> ": " <> localize (showRounded count)
)
)
)
areas
content =
defs_
[]
( linearGradient_
[ Id_ <<- "legend"
, X1_ <<- "0"
, X2_ <<- "1"
, Y1_ <<- "0"
, Y2_ <<- "0"
]
( stop_ [Offset_ <<- "0%", Stop_color_ <<- "white"]
<> stop_ [Offset_ <<- "100%", Stop_color_ <<- fillColor]
)
)
<> g_
[]
( rect_
[ X_ <<- "150"
, Y_ <<- "880"
, Stroke_ <<- frameColor
, Width_ <<- "350"
, Height_ <<- "10"
, Fill_ <<- "url(#legend)"
]
<> text_
[ X_ <<- "135"
, Y_ <<- "890"
, Font_size_ <<- "18"
, Fill_ <<- "black"
]
"0"
<> text_
[ X_ <<- "510"
, Y_ <<- "890"
, Font_size_ <<- "18"
, Fill_ <<- "black"
]
(toElement $ localize $ showRounded theMaximum)
)
<> g_ [] areaPaths