granite 0.7.1.0 → 0.7.1.1
raw patch · 9 files changed
+238/−128 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +3/−0
- granite.cabal +1/−1
- src/Granite/Render/Pipeline.hs +47/−8
- test/GoldenSpec.hs +42/−0
- test/golden/heatmap-continuous.svg +30/−0
- test/golden/plotly-heatmap-annotated.svg +55/−57
- test/golden/plotly-heatmap-annotated.txt +15/−15
- test/golden/plotly-heatmap.svg +30/−32
- test/golden/plotly-heatmap.txt +15/−15
CHANGELOG.md view
@@ -1,5 +1,8 @@ # Revision history for granite +## 0.7.1.1 -- 2026-05-25+* `GeomTile` honours a continuous `scaleFill` (`SColorContinuous`) via smooth RGB interpolation, and no longer emits a stray category legend entry.+ ## 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.
granite.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: granite-version: 0.7.1.0+version: 0.7.1.1 synopsis: Easy terminal plotting. description: A terminal plotting library for quick and easy visualisation. license: MIT
src/Granite/Render/Pipeline.hs view
@@ -67,6 +67,7 @@ Mapping (..), PolarAes (..), PolarDir (..),+ Scale (..), Scales (..), Size (..), Theme (..),@@ -147,12 +148,15 @@ Just t -> not (Text.null t) Nothing -> False colorMaps = map (layerColorMap palette (chartData chart)) (chartLayers chart)+ fillCols = case scaleFill (chartScales chart) of+ Just (SColorContinuous cs) -> Just cs+ _ -> Nothing legendEntries = collectLegend (chartLayers chart) palette colorMaps hasRightLegend = not (null legendEntries) box = computePlotBox (chartSize chart) theme hasTitle hasRightLegend False panels = layoutPanels theme box chart- panelMarks = concatMap (renderPanel theme palette coord colorMaps) panels+ panelMarks = concatMap (renderPanel theme palette coord colorMaps fillCols) panels legend = legendMarks theme box legendEntries title = titleMarks theme box (chartTitle chart)@@ -174,14 +178,24 @@ [ColorSpec] -> Coord -> [Maybe [(Text, ColorSpec)]] ->+ Maybe [ColorSpec] -> PanelSpec -> [Mark]-renderPanel theme palette coord colorMaps ps =+renderPanel theme palette coord colorMaps fillCols ps = let proj = buildProjector coord (panelBox ps) (panelXScale ps) (panelYScale ps) cmap i = if i < length colorMaps then colorMaps !! i else Nothing layerMarks = concat- [ runLayer theme (panelBox ps) proj palette (cmap i) i (panelData ps) layer+ [ runLayer+ theme+ (panelBox ps)+ proj+ palette+ (cmap i)+ fillCols+ i+ (panelData ps)+ layer | (i, layer) <- zip [0 :: Int ..] (panelLayers ps) ] axes = axesMarks theme (panelBox ps) coord (panelXScale ps) (panelYScale ps)@@ -414,11 +428,12 @@ Projector -> [ColorSpec] -> Maybe [(Text, ColorSpec)] ->+ Maybe [ColorSpec] -> Int -> DataFrame -> Layer -> [Mark]-runLayer theme box proj palette colorMap ix globalFrame layer =+runLayer theme box proj palette colorMap fillCols ix globalFrame layer = let frame0 = fromMaybe globalFrame (layerData layer) framePostStat = applyStat (layerStat layer) (layerMapping layer) frame0 frame = applyPosition (layerPosition layer) (layerMapping layer) framePostStat@@ -456,7 +471,7 @@ GeomHistogram -> drawBars proj frame m col GeomRibbon -> drawRibbon proj frame m col GeomErrorbar -> drawErrorbar proj frame m col- GeomTile -> drawTiles proj frame m col+ GeomTile -> drawTiles proj frame m col fillCols GeomBoxplot -> drawBoxplot proj frame m col GeomDensity -> drawDensity proj frame m col GeomText -> drawText proj frame m col (themeFontSize theme)@@ -580,8 +595,9 @@ ] _ -> [] -drawTiles :: Projector -> DataFrame -> Mapping -> Color -> [Mark]-drawTiles proj frame m col =+drawTiles ::+ Projector -> DataFrame -> Mapping -> Color -> Maybe [ColorSpec] -> [Mark]+drawTiles proj frame m col fillCols = case (resolveNumColumn frame (aesX m), resolveNumColumn frame (aesY m)) of (Just xs, Just ys) -> let wX = barWidth xs / 0.8@@ -600,7 +616,9 @@ if hi == lo then 0.5 else (vs !! i - lo) / (hi - lo)- in gradientColor t+ in case fillCols of+ Just cs -> continuousColorFor cs t+ Nothing -> gradientColor t _ -> col in [ rectFromCorners (proj (x - halfX) (y - halfY))@@ -625,6 +643,26 @@ ix = floor (clamped * fromIntegral n) :: Int in palette !! ix +{- | Map @t@ in [0,1] to a colour by piecewise-linear RGB interpolation across+the anchor colours (used to honour a continuous 'scaleFill' on tiles).+-}+continuousColorFor :: [ColorSpec] -> Double -> Color+continuousColorFor specs t =+ case map specToColor specs of+ [] -> gradientColor t+ [c] -> c+ colors ->+ let n = length colors+ clamped = max 0 (min 1 t)+ pos = clamped * fromIntegral (n - 1)+ i = min (n - 2) (floor pos)+ frac = pos - fromIntegral i+ Color r1 g1 b1 = colors !! i+ Color r2 g2 b2 = colors !! (i + 1)+ lerp a b =+ round (fromIntegral a + frac * (fromIntegral b - fromIntegral a))+ in Color (lerp r1 r2) (lerp g1 g2) (lerp b1 b2)+ drawBoxplot :: Projector -> DataFrame -> Mapping -> Color -> [Mark] drawBoxplot proj frame m col = case ( resolveNumColumn frame (aesX m)@@ -952,6 +990,7 @@ where entriesFor ix layer cmap | GeomText <- layerGeom layer = []+ | GeomTile <- layerGeom layer = [] | Just levelColors <- cmap = levelColors | otherwise = [(legendName ix layer, palette !! (ix `mod` max 1 (length palette)))]
test/GoldenSpec.hs view
@@ -24,6 +24,7 @@ import Granite.Spec ( BinSpec (..), Chart (..),+ ColorSpec (..), ColumnRef (..), Coord (..), Facet (..),@@ -266,6 +267,44 @@ , chartSize = SizeChars 30 16 } +-- A continuous-fill heatmap: GeomTile coloured by a numeric column through a+-- 'SColorContinuous' scaleFill (blue -> white -> red). Exercises the continuous+-- tile colour path + the suppressed tile legend.+contHeatmap :: Chart+contHeatmap =+ let coords =+ [ (fromIntegral x, fromIntegral y, fromIntegral (x + y) :: Double)+ | x <- [0 .. 3 :: Int]+ , y <- [0 .. 3 :: Int]+ ]+ df =+ fromColumns+ [ ("x", ColNum [x | (x, _, _) <- coords])+ , ("y", ColNum [y | (_, y, _) <- coords])+ , ("z", ColNum [z | (_, _, z) <- coords])+ ]+ tile =+ (defLayer GeomTile)+ { layerMapping =+ emptyMapping+ { aesX = Just (ColumnRef "x")+ , aesY = Just (ColumnRef "y")+ , aesFill = Just (ColumnRef "z")+ }+ , layerStat = StatIdentity+ }+ in emptyChart+ { chartData = df+ , chartLayers = [tile]+ , chartScales =+ defScales+ { scaleFill =+ Just (SColorContinuous [Hex "#2166ac", Hex "#f7f7f7", Hex "#b2182b"])+ }+ , chartTitle = Just "Continuous heatmap"+ , chartSize = SizeChars 40 14+ }+ -- A four-petal rose in polar coordinates: r = |sin(2θ)| sampled at 33 -- angular positions. Locks in the polar projector + polar chrome. polarRose :: Chart@@ -377,6 +416,9 @@ it "pie chart renders to expected SVG output" $ goldenText "pie-basic.svg" (renderChartSvg pieBasic)++ it "continuous-fill heatmap renders to expected SVG output" $+ goldenText "heatmap-continuous.svg" (renderChartSvg contHeatmap) describe "Sizing" $ do it "responsive scatter renders to expected SVG output" $
+ test/golden/heatmap-continuous.svg view
@@ -0,0 +1,30 @@+<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="380" 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="100.87" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">0.0</text>+<text x="178.62" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">1.0</text>+<text x="256.38" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">2.0</text>+<text x="334.13" y="211.20" text-anchor="middle" fill="#7f8c8d" font-size="11">3.0</text>+<text x="49" y="176.97" text-anchor="end" fill="#7f8c8d" font-size="11">0.0</text>+<text x="49" y="138.17" text-anchor="end" fill="#7f8c8d" font-size="11">1.0</text>+<text x="49" y="99.36" text-anchor="end" fill="#7f8c8d" font-size="11">2.0</text>+<text x="49" y="60.56" text-anchor="end" fill="#7f8c8d" font-size="11">3.0</text>+<rect x="62.00" y="153.90" width="77.75" height="38.80" fill="#2166ac"/>+<rect x="62.00" y="115.10" width="77.75" height="38.80" fill="#6896c5"/>+<rect x="62.00" y="76.30" width="77.75" height="38.80" fill="#b0c7de"/>+<rect x="62.00" y="37.49" width="77.75" height="38.80" fill="#f7f7f7"/>+<rect x="139.75" y="153.90" width="77.75" height="38.80" fill="#6896c5"/>+<rect x="139.75" y="115.10" width="77.75" height="38.80" fill="#b0c7de"/>+<rect x="139.75" y="76.30" width="77.75" height="38.80" fill="#f7f7f7"/>+<rect x="139.75" y="37.49" width="77.75" height="38.80" fill="#e0adb3"/>+<rect x="217.50" y="153.90" width="77.75" height="38.80" fill="#b0c7de"/>+<rect x="217.50" y="115.10" width="77.75" height="38.80" fill="#f7f7f7"/>+<rect x="217.50" y="76.30" width="77.75" height="38.80" fill="#e0adb3"/>+<rect x="217.50" y="37.49" width="77.75" height="38.80" fill="#c9626f"/>+<rect x="295.25" y="153.90" width="77.75" height="38.80" fill="#f7f7f7"/>+<rect x="295.25" y="115.10" width="77.75" height="38.80" fill="#e0adb3"/>+<rect x="295.25" y="76.30" width="77.75" height="38.80" fill="#c9626f"/>+<rect x="295.25" y="37.49" width="77.75" height="38.80" fill="#b2182b"/>+<text x="217.50" y="26" text-anchor="middle" fill="#7f8c8d" font-size="14">Continuous heatmap</text>+</svg>
test/golden/plotly-heatmap-annotated.svg view
@@ -1,64 +1,62 @@ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 256" width="480" height="256" font-family="system-ui, -apple-system, sans-serif"> <rect width="100%" height="100%" fill="white"/>-<line x1="55" y1="228.20" x2="360" y2="228.20" stroke="#ecf0f1" stroke-width="1"/>+<line x1="55" y1="228.20" x2="460" y2="228.20" stroke="#ecf0f1" stroke-width="1"/> <line x1="55" y1="34" x2="55" y2="228.20" stroke="#ecf0f1" stroke-width="1"/>-<text x="91.97" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">0.0</text>-<text x="207.50" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">2.0</text>-<text x="323.03" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">4.0</text>+<text x="104.09" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">0.0</text>+<text x="257.50" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">2.0</text>+<text x="410.91" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">4.0</text> <text x="49" y="208.33" text-anchor="end" fill="#7f8c8d" font-size="11">0.0</text> <text x="49" y="134.77" text-anchor="end" fill="#7f8c8d" font-size="11">2.0</text> <text x="49" y="61.21" text-anchor="end" fill="#7f8c8d" font-size="11">4.0</text>-<rect x="63.09" y="186.27" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="63.09" y="149.49" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="63.09" y="112.71" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="63.09" y="75.93" width="57.77" height="36.78" fill="#3498db"/>-<rect x="63.09" y="39.15" width="57.77" height="36.78" fill="#2980b9"/>-<rect x="120.85" y="186.27" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="120.85" y="149.49" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="120.85" y="112.71" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="120.85" y="75.93" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="120.85" y="39.15" width="57.77" height="36.78" fill="#3498db"/>-<rect x="178.62" y="186.27" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="178.62" y="149.49" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="178.62" y="112.71" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="178.62" y="75.93" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="178.62" y="39.15" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="236.38" y="186.27" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="236.38" y="149.49" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="236.38" y="112.71" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="236.38" y="75.93" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="236.38" y="39.15" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="294.15" y="186.27" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="294.15" y="149.49" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="294.15" y="112.71" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="294.15" y="75.93" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="294.15" y="39.15" width="57.77" height="36.78" fill="#1abc9c"/>-<text x="91.97" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.0</text>-<text x="91.97" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">0.9</text>-<text x="91.97" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">0.5</text>-<text x="91.97" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">0.1</text>-<text x="91.97" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">-0.4</text>-<text x="149.73" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.5</text>-<text x="149.73" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.4</text>-<text x="149.73" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.0</text>-<text x="149.73" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">0.6</text>-<text x="149.73" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.1</text>-<text x="207.50" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.8</text>-<text x="207.50" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.7</text>-<text x="207.50" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.4</text>-<text x="207.50" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">0.9</text>-<text x="207.50" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.4</text>-<text x="265.27" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">2.0</text>-<text x="265.27" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.9</text>-<text x="265.27" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.5</text>-<text x="265.27" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">1.1</text>-<text x="265.27" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.6</text>-<text x="323.03" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.9</text>-<text x="323.03" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.8</text>-<text x="323.03" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.4</text>-<text x="323.03" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">1.0</text>-<text x="323.03" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.5</text>-<text x="207.50" y="26" text-anchor="middle" fill="#7f8c8d" font-size="14">Annotated heatmap</text>-<rect x="375" y="39" width="12" height="12" fill="#3498db"/>-<text x="391" y="49" text-anchor="start" fill="#7f8c8d" font-size="11">series 0</text>+<rect x="65.74" y="186.27" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="65.74" y="149.49" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="65.74" y="112.71" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="65.74" y="75.93" width="76.70" height="36.78" fill="#3498db"/>+<rect x="65.74" y="39.15" width="76.70" height="36.78" fill="#2980b9"/>+<rect x="142.44" y="186.27" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="142.44" y="149.49" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="142.44" y="112.71" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="142.44" y="75.93" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="142.44" y="39.15" width="76.70" height="36.78" fill="#3498db"/>+<rect x="219.15" y="186.27" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="219.15" y="149.49" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="219.15" y="112.71" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="219.15" y="75.93" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="219.15" y="39.15" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="295.85" y="186.27" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="295.85" y="149.49" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="295.85" y="112.71" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="295.85" y="75.93" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="295.85" y="39.15" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="372.56" y="186.27" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="372.56" y="149.49" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="372.56" y="112.71" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="372.56" y="75.93" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="372.56" y="39.15" width="76.70" height="36.78" fill="#1abc9c"/>+<text x="104.09" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.0</text>+<text x="104.09" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">0.9</text>+<text x="104.09" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">0.5</text>+<text x="104.09" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">0.1</text>+<text x="104.09" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">-0.4</text>+<text x="180.80" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.5</text>+<text x="180.80" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.4</text>+<text x="180.80" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.0</text>+<text x="180.80" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">0.6</text>+<text x="180.80" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.1</text>+<text x="257.50" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.8</text>+<text x="257.50" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.7</text>+<text x="257.50" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.4</text>+<text x="257.50" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">0.9</text>+<text x="257.50" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.4</text>+<text x="334.20" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">2.0</text>+<text x="334.20" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.9</text>+<text x="334.20" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.5</text>+<text x="334.20" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">1.1</text>+<text x="334.20" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.6</text>+<text x="410.91" y="204.66" text-anchor="middle" fill="#9b59b6" font-size="11">1.9</text>+<text x="410.91" y="167.88" text-anchor="middle" fill="#9b59b6" font-size="11">1.8</text>+<text x="410.91" y="131.10" text-anchor="middle" fill="#9b59b6" font-size="11">1.4</text>+<text x="410.91" y="94.32" text-anchor="middle" fill="#9b59b6" font-size="11">1.0</text>+<text x="410.91" y="57.54" text-anchor="middle" fill="#9b59b6" font-size="11">0.5</text>+<text x="257.50" y="26" text-anchor="middle" fill="#7f8c8d" font-size="14">Annotated heatmap</text> </svg>
test/golden/plotly-heatmap-annotated.txt view
@@ -1,16 +1,16 @@ - [90mAnnotated heatmap [0m- [37m│[0m[34m██████[0m[94m█████[0m[96m███████████████████ [0m[94m██ [0m- [90m4.0 [0m[37m│[0m[34m█[0m[95m-0.4[0m[34m█[0m[94m█[0m[95m0.1[0m[94m█[0m[96m██[0m[95m0.4[0m[96m███[0m[95m0.6[0m[96m███[0m[95m0.5[0m[96m██ [0m[94m██[0m[90mseries 0 [0m- [37m│[0m[34m██████[0m[94m█████[0m[96m███████████████████ [0m- [37m│[0m[94m██[0m[95m0.1[0m[94m█[0m[96m█[0m[95m0.6[0m[96m█[0m[92m██[0m[95m0.9[0m[92m███[0m[95m1.1[0m[92m███[0m[95m1.0[0m[92m██ [0m- [37m│[0m[94m██████[0m[96m█████[0m[92m███████████████████ [0m- [37m│[0m[96m██████[0m[92m█████[0m[93m███████████████████ [0m- [90m2.0 [0m[37m│[0m[96m██[0m[95m0.5[0m[96m█[0m[92m█[0m[95m1.0[0m[92m█[0m[93m██[0m[95m1.4[0m[93m███[0m[95m1.5[0m[93m███[0m[95m1.4[0m[93m██ [0m- [37m│[0m[96m██████[0m[92m█████[0m[93m███████████████████ [0m- [37m│[0m[92m██[0m[95m0.9[0m[92m█[0m[93m█[0m[95m1.4[0m[93m█[0m[91m██[0m[95m1.7[0m[91m███[0m[95m1.9[0m[91m███[0m[95m1.8[0m[91m██ [0m- [37m│[0m[92m██████[0m[93m█████[0m[91m███████████████████ [0m- [37m│[0m[92m██[0m[95m1.0[0m[92m█[0m[93m█[0m[95m1.5[0m[93m█[0m[91m██[0m[95m1.8[0m[91m███[0m[95m2.0[0m[91m███[0m[95m1.9[0m[91m██ [0m- [90m0.0 [0m[37m│[0m[92m██████[0m[93m█████[0m[91m███████████████████ [0m- [37m┼─────────────────────────────── [0m- [90m0.0 2.0 4.0 [0m+ [90mAnnotated heatmap [0m+ [37m│[0m[34m████████[0m[94m███████[0m[96m████████████████████████ [0m+ [90m4.0 [0m[37m│[0m[34m██[0m[95m-0.4[0m[34m██[0m[94m███[0m[95m0.1[0m[94m█[0m[96m███[0m[95m0.4[0m[96m█████[0m[95m0.6[0m[96m█████[0m[95m0.5[0m[96m██ [0m+ [37m│[0m[34m████████[0m[94m███████[0m[96m████████████████████████ [0m+ [37m│[0m[94m███[0m[95m0.1[0m[94m██[0m[96m███[0m[95m0.6[0m[96m█[0m[92m███[0m[95m0.9[0m[92m█████[0m[95m1.1[0m[92m█████[0m[95m1.0[0m[92m██ [0m+ [37m│[0m[94m████████[0m[96m███████[0m[92m████████████████████████ [0m+ [37m│[0m[96m████████[0m[92m███████[0m[93m████████████████████████ [0m+ [90m2.0 [0m[37m│[0m[96m███[0m[95m0.5[0m[96m██[0m[92m███[0m[95m1.0[0m[92m█[0m[93m███[0m[95m1.4[0m[93m█████[0m[95m1.5[0m[93m█████[0m[95m1.4[0m[93m██ [0m+ [37m│[0m[96m████████[0m[92m███████[0m[93m████████████████████████ [0m+ [37m│[0m[92m███[0m[95m0.9[0m[92m██[0m[93m███[0m[95m1.4[0m[93m█[0m[91m███[0m[95m1.7[0m[91m█████[0m[95m1.9[0m[91m█████[0m[95m1.8[0m[91m██ [0m+ [37m│[0m[92m████████[0m[93m███████[0m[91m████████████████████████ [0m+ [37m│[0m[92m███[0m[95m1.0[0m[92m██[0m[93m███[0m[95m1.5[0m[93m█[0m[91m███[0m[95m1.8[0m[91m█████[0m[95m2.0[0m[91m█████[0m[95m1.9[0m[91m██ [0m+ [90m0.0 [0m[37m│[0m[92m████████[0m[93m███████[0m[91m████████████████████████ [0m+ [37m┼───────────────────────────────────────── [0m+ [90m0.0 2.0 4.0 [0m
test/golden/plotly-heatmap.svg view
@@ -1,39 +1,37 @@ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 256" width="480" height="256" font-family="system-ui, -apple-system, sans-serif"> <rect width="100%" height="100%" fill="white"/>-<line x1="55" y1="228.20" x2="360" y2="228.20" stroke="#ecf0f1" stroke-width="1"/>+<line x1="55" y1="228.20" x2="460" y2="228.20" stroke="#ecf0f1" stroke-width="1"/> <line x1="55" y1="34" x2="55" y2="228.20" stroke="#ecf0f1" stroke-width="1"/>-<text x="91.97" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">0.0</text>-<text x="207.50" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">2.0</text>-<text x="323.03" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">4.0</text>+<text x="104.09" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">0.0</text>+<text x="257.50" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">2.0</text>+<text x="410.91" y="243.20" text-anchor="middle" fill="#7f8c8d" font-size="11">4.0</text> <text x="49" y="208.33" text-anchor="end" fill="#7f8c8d" font-size="11">0.0</text> <text x="49" y="134.77" text-anchor="end" fill="#7f8c8d" font-size="11">2.0</text> <text x="49" y="61.21" text-anchor="end" fill="#7f8c8d" font-size="11">4.0</text>-<rect x="63.09" y="186.27" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="63.09" y="149.49" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="63.09" y="112.71" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="63.09" y="75.93" width="57.77" height="36.78" fill="#3498db"/>-<rect x="63.09" y="39.15" width="57.77" height="36.78" fill="#2980b9"/>-<rect x="120.85" y="186.27" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="120.85" y="149.49" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="120.85" y="112.71" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="120.85" y="75.93" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="120.85" y="39.15" width="57.77" height="36.78" fill="#3498db"/>-<rect x="178.62" y="186.27" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="178.62" y="149.49" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="178.62" y="112.71" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="178.62" y="75.93" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="178.62" y="39.15" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="236.38" y="186.27" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="236.38" y="149.49" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="236.38" y="112.71" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="236.38" y="75.93" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="236.38" y="39.15" width="57.77" height="36.78" fill="#1abc9c"/>-<rect x="294.15" y="186.27" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="294.15" y="149.49" width="57.77" height="36.78" fill="#e74c3c"/>-<rect x="294.15" y="112.71" width="57.77" height="36.78" fill="#f1c40f"/>-<rect x="294.15" y="75.93" width="57.77" height="36.78" fill="#2ecc71"/>-<rect x="294.15" y="39.15" width="57.77" height="36.78" fill="#1abc9c"/>-<text x="207.50" y="26" text-anchor="middle" fill="#7f8c8d" font-size="14">Heatmap</text>-<rect x="375" y="39" width="12" height="12" fill="#3498db"/>-<text x="391" y="49" text-anchor="start" fill="#7f8c8d" font-size="11">series 0</text>+<rect x="65.74" y="186.27" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="65.74" y="149.49" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="65.74" y="112.71" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="65.74" y="75.93" width="76.70" height="36.78" fill="#3498db"/>+<rect x="65.74" y="39.15" width="76.70" height="36.78" fill="#2980b9"/>+<rect x="142.44" y="186.27" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="142.44" y="149.49" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="142.44" y="112.71" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="142.44" y="75.93" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="142.44" y="39.15" width="76.70" height="36.78" fill="#3498db"/>+<rect x="219.15" y="186.27" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="219.15" y="149.49" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="219.15" y="112.71" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="219.15" y="75.93" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="219.15" y="39.15" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="295.85" y="186.27" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="295.85" y="149.49" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="295.85" y="112.71" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="295.85" y="75.93" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="295.85" y="39.15" width="76.70" height="36.78" fill="#1abc9c"/>+<rect x="372.56" y="186.27" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="372.56" y="149.49" width="76.70" height="36.78" fill="#e74c3c"/>+<rect x="372.56" y="112.71" width="76.70" height="36.78" fill="#f1c40f"/>+<rect x="372.56" y="75.93" width="76.70" height="36.78" fill="#2ecc71"/>+<rect x="372.56" y="39.15" width="76.70" height="36.78" fill="#1abc9c"/>+<text x="257.50" y="26" text-anchor="middle" fill="#7f8c8d" font-size="14">Heatmap</text> </svg>
test/golden/plotly-heatmap.txt view
@@ -1,16 +1,16 @@ - [90mHeatmap [0m- [37m│[0m[34m██████[0m[94m█████[0m[96m███████████████████ [0m[94m██ [0m- [90m4.0 [0m[37m│[0m[34m██████[0m[94m█████[0m[96m███████████████████ [0m[94m██[0m[90mseries 0 [0m- [37m│[0m[34m██████[0m[94m█████[0m[96m███████████████████ [0m- [37m│[0m[94m██████[0m[96m█████[0m[92m███████████████████ [0m- [37m│[0m[94m██████[0m[96m█████[0m[92m███████████████████ [0m- [37m│[0m[96m██████[0m[92m█████[0m[93m███████████████████ [0m- [90m2.0 [0m[37m│[0m[96m██████[0m[92m█████[0m[93m███████████████████ [0m- [37m│[0m[96m██████[0m[92m█████[0m[93m███████████████████ [0m- [37m│[0m[92m██████[0m[93m█████[0m[91m███████████████████ [0m- [37m│[0m[92m██████[0m[93m█████[0m[91m███████████████████ [0m- [37m│[0m[92m██████[0m[93m█████[0m[91m███████████████████ [0m- [90m0.0 [0m[37m│[0m[92m██████[0m[93m█████[0m[91m███████████████████ [0m- [37m┼─────────────────────────────── [0m- [90m0.0 2.0 4.0 [0m+ [90mHeatmap [0m+ [37m│[0m[34m████████[0m[94m███████[0m[96m████████████████████████ [0m+ [90m4.0 [0m[37m│[0m[34m████████[0m[94m███████[0m[96m████████████████████████ [0m+ [37m│[0m[34m████████[0m[94m███████[0m[96m████████████████████████ [0m+ [37m│[0m[94m████████[0m[96m███████[0m[92m████████████████████████ [0m+ [37m│[0m[94m████████[0m[96m███████[0m[92m████████████████████████ [0m+ [37m│[0m[96m████████[0m[92m███████[0m[93m████████████████████████ [0m+ [90m2.0 [0m[37m│[0m[96m████████[0m[92m███████[0m[93m████████████████████████ [0m+ [37m│[0m[96m████████[0m[92m███████[0m[93m████████████████████████ [0m+ [37m│[0m[92m████████[0m[93m███████[0m[91m████████████████████████ [0m+ [37m│[0m[92m████████[0m[93m███████[0m[91m████████████████████████ [0m+ [37m│[0m[92m████████[0m[93m███████[0m[91m████████████████████████ [0m+ [90m0.0 [0m[37m│[0m[92m████████[0m[93m███████[0m[91m████████████████████████ [0m+ [37m┼───────────────────────────────────────── [0m+ [90m0.0 2.0 4.0 [0m