granite 0.7.0.0 → 0.7.1.0
raw patch · 5 files changed
+70/−6 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- granite.cabal +1/−1
- src/Granite/Render/Pipeline.hs +13/−5
- test/GoldenSpec.hs +29/−0
- test/golden/scatter-alpha.svg +23/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for granite +## 0.7.1.0 -- 2026-05-25++* Numeric `aesAlpha` mappings are now honoured for points (per-point opacity); previously only the per-layer `defAlpha` was applied.+ ## 0.7.0.0 -- 2026-05-24 * `Color` is now a 24-bit RGB value, and categorical colour mappings are honoured for points.
granite.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: granite-version: 0.7.0.0+version: 0.7.1.0 synopsis: Easy terminal plotting. description: A terminal plotting library for quick and easy visualisation. license: MIT
src/Granite/Render/Pipeline.hs view
@@ -440,8 +440,16 @@ | Just cats <- categoricalColorColumn frame m -> map (\cat -> specToColor (fromMaybe colorSpec (lookup cat levelColors))) cats _ -> repeat col+ pointAlphas = case resolveNumColumn frame (aesAlpha m) of+ Just vs@(_ : _) ->+ let lo = minimum vs+ hi = maximum vs+ in if hi <= lo+ then repeat alpha+ else map (\v -> 0.15 + 0.85 * (v - lo) / (hi - lo)) vs+ _ -> repeat alpha in case layerGeom layer of- GeomPoint -> drawPoints proj frame m pointColors radius alpha+ GeomPoint -> drawPoints proj frame m pointColors radius pointAlphas GeomLine -> drawLine proj frame m colorSpec lineW GeomBar -> drawBars proj frame m col GeomCol -> drawBars proj frame m col@@ -460,9 +468,9 @@ Mapping -> [Color] -> Double ->- Double ->+ [Double] -> [Mark]-drawPoints proj frame m cols r alpha =+drawPoints proj frame m cols r alphas = case (resolveNumColumn frame (aesX m), resolveNumColumn frame (aesY m)) of (Just xv, Just yv) -> [ MCircle@@ -470,9 +478,9 @@ r defaultStyle { styleFill = Just c- , styleFillOpacity = alpha+ , styleFillOpacity = a }- | ((x, y), c) <- zip (zip xv yv) cols+ | ((x, y), c, a) <- zip3 (zip xv yv) cols alphas ] _ -> []
test/GoldenSpec.hs view
@@ -63,6 +63,32 @@ ] (Just "Random points") +-- A scatter whose point opacity is driven by a numeric column via 'aesAlpha':+-- low weight -> faint, high weight -> opaque. Locks in per-point alpha.+alphaScatter :: Chart+alphaScatter =+ let df =+ fromColumns+ [ ("x", ColNum [0, 1, 2, 3, 4])+ , ("y", ColNum [0, 1, 2, 3, 4])+ , ("w", ColNum [1, 2, 3, 4, 5])+ ]+ layer =+ (defLayer GeomPoint)+ { layerMapping =+ emptyMapping+ { aesX = Just (ColumnRef "x")+ , aesY = Just (ColumnRef "y")+ , aesAlpha = Just (ColumnRef "w")+ }+ }+ in emptyChart+ { chartData = df+ , chartLayers = [layer]+ , chartTitle = Just "Alpha by weight"+ , chartSize = SizeChars 40 14+ }+ singleSeriesLine :: Chart singleSeriesLine = lineChart@@ -295,6 +321,9 @@ it "no-title scatter renders to expected SVG output" $ goldenText "scatter-no-title.svg" (renderChartSvg noTitleScatter)++ it "alpha-mapped scatter renders to expected SVG output" $+ goldenText "scatter-alpha.svg" (renderChartSvg alphaScatter) describe "Line chart" $ do it "single-series line renders to expected terminal output" $
+ test/golden/scatter-alpha.svg view
@@ -0,0 +1,23 @@+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 224" width="400" height="224" font-family="system-ui, -apple-system, sans-serif">+<rect width="100%" height="100%" fill="white"/>+<line x1="55" y1="196.20" x2="280" y2="196.20" stroke="#ecf0f1" stroke-width="1"/>+<line x1="55" y1="34" x2="55" y2="196.20" stroke="#ecf0f1" stroke-width="1"/>+<text x="65.23" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">0.0</text>+<text x="116.36" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">1.0</text>+<text x="167.50" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">2.0</text>+<text x="218.64" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">3.0</text>+<text x="269.77" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">4.0</text>+<text x="49" y="192.49" text-anchor="end" fill="#7f8c8d" font-size="11">0.0</text>+<text x="49" y="155.63" text-anchor="end" fill="#7f8c8d" font-size="11">1.0</text>+<text x="49" y="118.77" text-anchor="end" fill="#7f8c8d" font-size="11">2.0</text>+<text x="49" y="81.90" text-anchor="end" fill="#7f8c8d" font-size="11">3.0</text>+<text x="49" y="45.04" text-anchor="end" fill="#7f8c8d" font-size="11">4.0</text>+<circle cx="65.23" cy="188.83" r="3" fill="#3498db" fill-opacity="0.15"/>+<circle cx="116.36" cy="151.96" r="3" fill="#3498db" fill-opacity="0.36"/>+<circle cx="167.50" cy="115.10" r="3" fill="#3498db" fill-opacity="0.58"/>+<circle cx="218.64" cy="78.24" r="3" fill="#3498db" fill-opacity="0.79"/>+<circle cx="269.77" cy="41.37" r="3" fill="#3498db"/>+<text x="167.50" y="26" text-anchor="middle" fill="#7f8c8d" font-size="14">Alpha by weight</text>+<rect x="295" y="39" width="12" height="12" fill="#3498db"/>+<text x="311" y="49" text-anchor="start" fill="#7f8c8d" font-size="11">series 0</text>+</svg>