hydroxy

Contour chart

Show a measure that varies across a surface, as marching-squares contour lines, a filled heat field, or both. HeatField is the filled form on its own. Hover, touch or move through the grid with the arrow keys to read any cell.

Elevation in metres
RowColumn 1Column 2Column 3Column 4Column 5Column 6Column 7Column 8Column 9Column 10Column 11Column 12Column 13Column 14Column 15Column 16Column 17Column 18Column 19Column 20Column 21Column 22Column 23Column 24Column 25Column 26Column 27Column 28Column 29Column 30Column 31Column 32Column 33Column 34Column 35Column 36
Row 13 m4 m6 m8 m11 m15 m18 m22 m25 m28 m30 m30 m30 m28 m26 m23 m20 m17 m14 m12 m10 m9 m8 m7 m7 m6 m6 m6 m5 m5 m4 m3 m3 m2 m2 m1 m
Row 23 m5 m8 m11 m15 m19 m24 m28 m33 m36 m39 m39 m39 m37 m34 m30 m26 m22 m19 m16 m13 m12 m11 m10 m9 m9 m8 m8 m7 m7 m6 m5 m4 m3 m3 m2 m
Row 34 m7 m10 m14 m18 m24 m30 m35 m41 m45 m48 m49 m49 m46 m43 m38 m33 m28 m24 m20 m18 m16 m14 m13 m13 m12 m12 m11 m10 m9 m8 m7 m6 m5 m4 m3 m
Row 45 m8 m12 m16 m22 m28 m35 m42 m49 m54 m58 m59 m58 m56 m51 m46 m40 m34 m29 m25 m22 m20 m18 m17 m17 m16 m15 m14 m13 m12 m11 m9 m8 m6 m5 m4 m
Row 56 m9 m13 m19 m25 m33 m41 m49 m56 m62 m66 m68 m67 m64 m59 m53 m47 m41 m35 m30 m27 m25 m23 m22 m21 m21 m20 m19 m17 m16 m14 m12 m10 m8 m6 m5 m
Row 67 m10 m15 m21 m28 m36 m45 m54 m62 m69 m73 m75 m75 m72 m66 m60 m53 m46 m40 m35 m32 m30 m28 m27 m27 m26 m25 m24 m22 m20 m17 m15 m13 m10 m8 m6 m
Row 77 m11 m16 m22 m29 m38 m48 m57 m66 m73 m78 m80 m80 m76 m71 m65 m57 m51 m45 m40 m37 m35 m34 m33 m33 m32 m31 m29 m27 m24 m22 m18 m15 m12 m10 m8 m
Row 87 m11 m16 m22 m30 m39 m49 m58 m67 m75 m80 m82 m82 m79 m74 m67 m60 m54 m48 m44 m42 m40 m39 m39 m39 m38 m37 m35 m32 m29 m26 m22 m18 m15 m12 m9 m
Row 97 m11 m16 m22 m30 m38 m48 m57 m66 m74 m79 m81 m81 m78 m73 m68 m61 m56 m51 m48 m45 m45 m44 m45 m44 m44 m43 m41 m38 m34 m30 m26 m21 m17 m14 m11 m
Row 107 m10 m15 m21 m28 m36 m45 m54 m63 m70 m74 m77 m77 m75 m71 m66 m60 m56 m52 m50 m49 m48 m49 m50 m50 m50 m48 m46 m43 m39 m34 m29 m24 m20 m16 m12 m
Row 116 m9 m13 m19 m25 m33 m41 m49 m57 m63 m68 m70 m71 m69 m66 m62 m58 m54 m52 m51 m51 m51 m53 m54 m54 m54 m53 m50 m47 m43 m37 m32 m27 m22 m17 m13 m
Row 125 m8 m12 m16 m22 m28 m36 m43 m50 m55 m59 m62 m62 m61 m59 m56 m54 m52 m51 m51 m52 m53 m55 m57 m58 m58 m57 m54 m50 m46 m40 m34 m29 m23 m18 m14 m
Row 134 m7 m10 m14 m18 m24 m30 m36 m42 m46 m50 m52 m53 m53 m52 m50 m49 m48 m48 m49 m51 m54 m57 m59 m60 m60 m59 m56 m52 m47 m42 m36 m30 m24 m19 m15 m
Row 143 m5 m8 m11 m15 m19 m24 m29 m34 m38 m41 m43 m44 m44 m44 m43 m43 m44 m45 m47 m50 m53 m56 m59 m60 m61 m60 m57 m53 m48 m42 m36 m30 m25 m19 m15 m
Row 153 m4 m6 m8 m11 m15 m19 m22 m26 m29 m32 m34 m35 m36 m36 m37 m37 m39 m41 m44 m48 m51 m55 m58 m59 m60 m59 m56 m52 m47 m42 m36 m30 m24 m19 m15 m
Row 162 m3 m4 m6 m8 m11 m14 m17 m20 m22 m24 m26 m27 m28 m29 m30 m32 m34 m37 m41 m45 m48 m52 m55 m57 m57 m56 m54 m50 m45 m40 m34 m29 m23 m18 m14 m
Row 171 m2 m3 m4 m6 m8 m10 m12 m14 m16 m18 m19 m21 m22 m23 m25 m27 m29 m33 m37 m41 m45 m48 m51 m53 m53 m52 m50 m47 m42 m37 m32 m27 m22 m17 m13 m
Row 181 m1 m2 m3 m4 m5 m7 m8 m10 m11 m13 m14 m15 m16 m18 m20 m22 m25 m28 m32 m36 m40 m43 m46 m48 m48 m48 m46 m42 m38 m34 m29 m24 m20 m16 m12 m
Row 191 m1 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m14 m16 m18 m21 m24 m28 m31 m35 m38 m41 m42 m43 m42 m40 m37 m34 m30 m26 m21 m17 m14 m11 m
Row 200 m1 m1 m1 m2 m2 m3 m4 m4 m5 m6 m7 m8 m9 m11 m12 m15 m17 m20 m23 m27 m30 m33 m35 m36 m36 m36 m34 m32 m29 m26 m22 m18 m15 m12 m9 m
Elevation contours
RowColumn 1Column 2Column 3Column 4Column 5Column 6Column 7Column 8Column 9Column 10Column 11Column 12Column 13Column 14Column 15Column 16Column 17Column 18Column 19Column 20Column 21Column 22Column 23Column 24Column 25Column 26Column 27Column 28Column 29Column 30Column 31Column 32Column 33Column 34Column 35Column 36
Row 12.74.15.98.411.314.618.221.925.227.929.730.430.028.526.123.220.117.014.211.810.08.77.77.16.76.36.05.65.24.64.13.52.92.41.91.4
Row 23.55.37.710.814.619.023.728.432.736.238.539.538.937.034.030.326.322.318.715.813.411.810.69.99.38.98.47.97.36.65.84.94.13.32.62.0
Row 34.36.69.613.518.223.729.535.440.745.148.149.348.646.342.638.033.128.223.920.317.515.514.213.312.712.111.610.910.09.07.96.85.74.63.62.8
Row 45.27.911.516.221.828.335.342.348.854.157.659.158.455.751.345.940.134.429.425.222.119.818.417.416.716.115.414.513.412.110.69.17.66.24.93.7
Row 55.99.013.218.625.132.640.748.756.262.266.468.167.464.359.453.446.940.534.930.427.024.623.122.221.520.820.018.817.415.713.811.89.98.06.34.9
Row 66.610.014.620.627.836.045.053.962.168.973.575.574.771.566.359.852.846.140.235.532.029.728.327.526.826.125.123.822.019.917.515.012.510.18.06.2
Row 77.010.615.521.829.538.347.857.366.073.378.280.479.876.571.264.557.450.744.840.237.034.933.833.132.631.930.829.227.124.421.518.515.412.59.97.6
Row 87.110.815.922.330.139.148.858.567.574.980.082.481.978.873.667.260.353.948.544.341.540.039.238.938.638.036.834.932.429.325.822.118.415.011.89.1
Row 97.010.615.521.929.538.347.857.466.373.678.781.280.978.173.467.561.355.650.947.545.544.644.444.544.544.042.740.637.734.130.025.721.517.413.810.6
Row 106.610.014.620.627.836.145.154.262.669.574.577.077.074.770.665.660.455.752.049.748.648.549.049.649.949.548.245.942.638.634.029.224.319.815.612.0
Row 116.09.113.318.625.232.740.949.156.863.267.870.370.668.965.761.757.754.351.950.750.651.452.753.854.554.353.050.546.942.537.532.126.821.817.213.2
Row 125.27.911.516.221.928.535.642.849.555.259.461.862.461.359.156.353.751.650.550.651.653.355.357.058.057.956.654.050.345.540.234.428.723.318.414.2
Row 134.36.69.613.618.323.829.835.941.646.550.252.453.252.851.650.048.647.948.249.451.453.956.558.760.060.158.956.352.447.541.835.930.024.319.214.8
Row 143.55.37.710.914.719.224.028.933.637.740.842.943.944.143.743.243.143.645.047.250.153.356.458.960.560.859.657.053.148.142.436.430.424.719.515.0
Row 152.74.16.08.411.414.818.622.526.129.432.033.935.135.736.136.637.438.941.244.247.851.454.957.759.459.858.756.252.347.441.835.930.024.319.214.8
Row 162.03.04.46.38.511.013.916.819.622.224.326.027.228.229.230.331.934.237.140.644.548.552.154.956.757.256.253.850.245.540.134.428.723.318.414.2
Row 171.42.23.24.56.17.910.012.114.216.117.819.320.621.823.124.726.829.532.836.540.644.548.151.052.853.352.450.246.842.437.432.126.821.817.213.2
Row 181.01.52.23.14.25.56.98.49.911.412.714.015.216.518.019.822.225.028.432.236.139.943.446.147.848.347.545.542.438.534.029.124.319.815.612.0
Row 190.61.01.42.02.83.64.65.66.77.88.89.911.012.313.815.718.120.924.127.731.434.938.040.542.142.541.940.237.434.030.025.721.517.413.810.6
Row 200.40.60.91.31.82.33.03.74.45.26.06.97.99.110.512.314.517.120.123.326.629.732.534.736.036.535.934.532.129.125.722.118.415.011.89.1
Elevation heat field
RowColumn 1Column 2Column 3Column 4Column 5Column 6Column 7Column 8Column 9Column 10Column 11Column 12Column 13Column 14Column 15Column 16Column 17Column 18Column 19Column 20Column 21Column 22Column 23Column 24Column 25Column 26Column 27Column 28Column 29Column 30Column 31Column 32Column 33Column 34Column 35Column 36
Row 12.74.15.98.411.314.618.221.925.227.929.730.430.028.526.123.220.117.014.211.810.08.77.77.16.76.36.05.65.24.64.13.52.92.41.91.4
Row 23.55.37.710.814.619.023.728.432.736.238.539.538.937.034.030.326.322.318.715.813.411.810.69.99.38.98.47.97.36.65.84.94.13.32.62.0
Row 34.36.69.613.518.223.729.535.440.745.148.149.348.646.342.638.033.128.223.920.317.515.514.213.312.712.111.610.910.09.07.96.85.74.63.62.8
Row 45.27.911.516.221.828.335.342.348.854.157.659.158.455.751.345.940.134.429.425.222.119.818.417.416.716.115.414.513.412.110.69.17.66.24.93.7
Row 55.99.013.218.625.132.640.748.756.262.266.468.167.464.359.453.446.940.534.930.427.024.623.122.221.520.820.018.817.415.713.811.89.98.06.34.9
Row 66.610.014.620.627.836.045.053.962.168.973.575.574.771.566.359.852.846.140.235.532.029.728.327.526.826.125.123.822.019.917.515.012.510.18.06.2
Row 77.010.615.521.829.538.347.857.366.073.378.280.479.876.571.264.557.450.744.840.237.034.933.833.132.631.930.829.227.124.421.518.515.412.59.97.6
Row 87.110.815.922.330.139.148.858.567.574.980.082.481.978.873.667.260.353.948.544.341.540.039.238.938.638.036.834.932.429.325.822.118.415.011.89.1
Row 97.010.615.521.929.538.347.857.466.373.678.781.280.978.173.467.561.355.650.947.545.544.644.444.544.544.042.740.637.734.130.025.721.517.413.810.6
Row 106.610.014.620.627.836.145.154.262.669.574.577.077.074.770.665.660.455.752.049.748.648.549.049.649.949.548.245.942.638.634.029.224.319.815.612.0
Row 116.09.113.318.625.232.740.949.156.863.267.870.370.668.965.761.757.754.351.950.750.651.452.753.854.554.353.050.546.942.537.532.126.821.817.213.2
Row 125.27.911.516.221.928.535.642.849.555.259.461.862.461.359.156.353.751.650.550.651.653.355.357.058.057.956.654.050.345.540.234.428.723.318.414.2
Row 134.36.69.613.618.323.829.835.941.646.550.252.453.252.851.650.048.647.948.249.451.453.956.558.760.060.158.956.352.447.541.835.930.024.319.214.8
Row 143.55.37.710.914.719.224.028.933.637.740.842.943.944.143.743.243.143.645.047.250.153.356.458.960.560.859.657.053.148.142.436.430.424.719.515.0
Row 152.74.16.08.411.414.818.622.526.129.432.033.935.135.736.136.637.438.941.244.247.851.454.957.759.459.858.756.252.347.441.835.930.024.319.214.8
Row 162.03.04.46.38.511.013.916.819.622.224.326.027.228.229.230.331.934.237.140.644.548.552.154.956.757.256.253.850.245.540.134.428.723.318.414.2
Row 171.42.23.24.56.17.910.012.114.216.117.819.320.621.823.124.726.829.532.836.540.644.548.151.052.853.352.450.246.842.437.432.126.821.817.213.2
Row 181.01.52.23.14.25.56.98.49.911.412.714.015.216.518.019.822.225.028.432.236.139.943.446.147.848.347.545.542.438.534.029.124.319.815.612.0
Row 190.61.01.42.02.83.64.65.66.77.88.89.911.012.313.815.718.120.924.127.731.434.938.040.542.142.541.940.237.434.030.025.721.517.413.810.6
Row 200.40.60.91.31.82.33.03.74.45.26.06.97.99.110.512.314.517.120.123.326.629.732.534.736.036.535.934.532.129.125.722.118.415.011.89.1

Usage

use hydroxy_leptos::contour_chart::*;
use leptos::prelude::*;

/// Two overlapping hills on a 36 × 20 grid.
fn terrain() -> Vec<f64> {
    let hill = |x: f64, y: f64, cx: f64, cy: f64, h: f64, r: f64| {
        h * (-((x - cx).powi(2) + (y - cy).powi(2)) / (2.0 * r * r)).exp()
    };
    (0..20)
        .flat_map(|r| (0..36).map(move |c| (f64::from(c), f64::from(r))))
        .map(|(x, y)| hill(x, y, 11.0, 7.0, 80.0, 5.0) + hill(x, y, 25.0, 13.0, 60.0, 6.0))
        .collect()
}

#[component]
pub fn Demo() -> impl IntoView {
    view! {
        <div style="display: grid; gap: var(--space-10);">
            // Contour lines at nice levels, over a filled heat field.
            <ContourChart values=terrain() columns=36 label="Elevation in metres" filled=true format=|v: f64| format!("{v:.0} m") />
            // Lines alone.
            <ContourChart values=terrain() columns=36 label="Elevation contours" levels=8 />
            // A heat field alone.
            <HeatField values=terrain() columns=36 label="Elevation heat field" />
        </div>
    }
}

Anatomy

Componentdata-partRenders
ContourChartrootfigure holding the plot, scale and screen-reader parts
plotFocusable group; reads the cell under the pointer
cellOne square per value, shaded on a sequential scale (filled only); fades in
contourA line at one level; darker for higher levels; draws in along its length
active-cellOutline on the cell being read
tooltipRow, column and value of the cell being read
scaleColour ramp with the smallest and largest value
sr-liveAnnounces the cell being read
sr-tableThe whole grid with a header row, for screen readers and CSV export

Keyboard

KeyDoes
Arrow keysMove between cells
Home / EndFirst or last cell in the row
EscapeClear the active cell

Props

PropTypeNotes
valuesVec<f64>Required. Row-major grid; NaN leaves a gap
columnsusizeRequired. Values per row
labelStringRequired. What the chart shows; the accessible name
levelsusizeAbout how many contour levels. Default 6
filledboolShade each cell under the lines (ContourChart only)
formatFn(f64) -> StringFormats the scale, tooltips and table

Events

PropTypeNotes
on_hoverCallback<Option<Datum>>The mark under the pointer or keyboard focus changes, or is left. Fires only on a change
on_selectCallback<Datum>Click, tap or Enter on a mark
Actions
Button
Icon button
Toolbar
Theme menu
Display
Avatar
Badge
Card
Chip
Code block
Markdown
Doc card
Due pill
Kbd
Priority mark
Source chip
Space icon
Status diamond
Tag
Value diff
Carousel
Reveal
Media timeline
QR code
Transcript viewer
Audio waveform
Audio player
Forms
Calendar
Checkbox
Combobox
Date picker
Color picker
Cron builder
Theme editor
Mention input
Signature pad
Image cropper
Date field
Date range picker
Duration field
Quantity stepper
Filter chip
Input
Markdown editor
Radio group
Search field
Segmented control
Select
Slider
Range slider
Rating
Toggle button
File dropzone
Upload queue
Attachment
Switch
Tags input
Number field
Money field
Phone field
Time field
OTP input
Password field
Questionnaire
Availability picker
Voice input
Recording control
Inline edit
Async validated input
Shortcut recorder
Data
Spreadsheet grid
Week scheduler
Virtual list
Stat card
Step track
Kanban board
Sortable list
Filter builder
Data table
Grid
Access editor
File manager
Gantt chart
Log stream
Diff viewer
JSON inspector
Terminal
Node editor
Whiteboard
Navigation
Table of contents
Breadcrumb
Tabs
Wizard
Nav item
Nav section
Tree view
Pagination
Menubar
Navigation menu
Saved views
Layout
Master detail
App shell
Sidebar layout
Resizable panels
Dashboard layout
Dock layout
Feedback
Callout
Check list
Empty state
Progress bar
Toast
Approval card
Skeleton
Notification center
Bars
Bar chart
Diverging bar chart
Span chart
Pictogram chart
Stacked bar chart
Funnel chart
Bullet chart
Waffle chart
Marimekko chart
Dot plot chart
Error bar chart
Pareto chart
Waterfall chart
Lollipop chart
Grouped bar chart
Bar race chart
KPIs and frames
Chart frame
Metric card
Sparkline
Points
Scatter chart
Smith chart
Strip plot
Beeswarm chart
Parallel coordinates
Ternary chart
Bland-Altman chart
Quiver chart
Connected scatter chart
Grids and tables
Heatmap chart
Chart table
Cohort chart
Radial
Radial charts
Radar chart
Polar area chart
Stat ring
Clock chart
Spiral chart
Lines and areas
Bump chart
Slope chart
Line chart
Composed chart
Small multiples
Cycle plot chart
Horizon chart
Stacked area chart
Threshold chart
Split line chart
Linked charts
Confidence band chart
Forecast fan chart
Step chart
Range area chart
Distributions
Contour chart
Histogram
Box plot
Density chart
Ridgeline chart
Violin chart
Q-Q chart
Survival chart
ECDF chart
Raincloud plot
Forest plot
Maps
Geo map
Bubble map
Hexbin map
Cartogram
Flow map
Parts of a whole
Donut chart
Voronoi treemap
Nested donut chart
Treemap chart
Sunburst chart
Bubble pack chart
Icicle chart
Flame graph chart
Pie chart
Word cloud
Relationships
Sankey chart
Network chart
Chord chart
UpSet chart
Venn chart
Alluvial chart
Adjacency matrix chart
Dependency graph chart
Tree chart
Arc diagram
Hive plot
Edge bundling
Finance
Candlestick chart
OHLC chart
Depth chart
Renko chart
Time
Timeline chart
Calendar heatmap chart
Spectrogram chart
Marey chart
Overlays
Tour
Lightbox
Alert dialog
Command palette
Dialog
Menu
Popover
Tooltip
Sheet
Hover card
Context menu
Utilities
Pacer
Hotkeys
Disclosure
Accordion
Collapsible
Chat
Chat bubble
Voice session
Composer
Thread
Thread list
Assistant composer
Assistant MCP
Assistant modal
Assistant thread
Assistant thread list
Message scroller
Insight note
Emoji picker
Tool trace
Model picker
Citation popover
Activity
Activity feed
Comment thread
Timeline
Presence bar
Live cursors
Reaction bar
Guides
Getting started
All components
All charts