Blazorise SVG Chart Zoom and Pan

Zoom and pan native SVG charts with declarative options and event callbacks.

SVG chart zoom can be enabled declaratively with SvgChartZoom or configured through SvgChartOptions.Zoom. Use ViewportChanged, Zoomed, and Panned to track viewport changes.

Examples

Navigation

Wheel over the chart to zoom, and drag the plot area to pan.
1 series, 0 categories.Store performanceXY zoom with numeric grid lines010203040506070020406080100120140Stores

Wheel over the chart to zoom, or drag the plot area to pan.

<SvgScatterChart TItem="StorePerformance"
                 Items="@stores"
                 Options="@options"
                 Hovered="@OnPointHovered">
    <SvgChartTitle Title='@("Store performance")' Subtitle='@("XY zoom with numeric grid lines")' />
    <SvgChartTooltip Enabled />
    <SvgChartValueAxis BeginAtZero TickCount="7" GridLines="@gridLines" />
    <SvgChartZoom Enabled
                  Mode="SvgChartZoomMode.XY"
                  MaxZoom="120"
                  Viewport="@viewport"
                  ViewportChanged="@OnViewportChanged"
                  Zoomed="@OnZoomed"
                  Panned="@OnPanned" />

    <SvgScatterSeries Name="Stores" XValue="@( item => item.Traffic )" YValue="@( item => item.Sales )" Color="Color.Primary" MarkerRadius="5" />
</SvgScatterChart>

<Paragraph Margin="Margin.Is2.FromTop.Is0.FromBottom">@lastEvent</Paragraph>
@code {
    private string lastEvent = "Wheel over the chart to zoom, or drag the plot area to pan.";

    private SvgChartViewport viewport;

    private readonly SvgChartGridLinesOptions gridLines = new()
    {
        Visible = true,
        Opacity = 0.2,
    };

    private readonly SvgChartOptions options = new()
    {
        Height = 360,
        XAxis = new() { BeginAtZero = false, TickCount = 7, GridLines = new() { Visible = true, Opacity = 0.2 } },
        YAxis = new() { BeginAtZero = true, TickCount = 7 },
        Zoom = new() { Enabled = true, Mode = SvgChartZoomMode.XY, MaxZoom = 120 },
    };

    private readonly List<StorePerformance> stores =
    [
        new() { Traffic = 8, Sales = 42 },
        new() { Traffic = 12, Sales = 55 },
        new() { Traffic = 16, Sales = 64 },
        new() { Traffic = 22, Sales = 58 },
        new() { Traffic = 29, Sales = 91 },
        new() { Traffic = 34, Sales = 76 },
        new() { Traffic = 42, Sales = 112 },
        new() { Traffic = 48, Sales = 108 },
        new() { Traffic = 53, Sales = 132 },
        new() { Traffic = 61, Sales = 126 },
    ];

    private Task OnPointHovered( SvgChartPointEventArgs eventArgs )
    {
        lastEvent = $"Hovered {eventArgs.SeriesName} / {eventArgs.Category}: {eventArgs.Value}";

        return Task.CompletedTask;
    }

    private Task OnViewportChanged( SvgChartViewport changedViewport )
    {
        viewport = changedViewport;

        return Task.CompletedTask;
    }

    private Task OnZoomed( SvgChartZoomedEventArgs eventArgs )
    {
        lastEvent = $"Zoomed viewport X {eventArgs.Viewport.XMin:0.##}-{eventArgs.Viewport.XMax:0.##}, Y {eventArgs.Viewport.YMin:0.##}-{eventArgs.Viewport.YMax:0.##}";

        return Task.CompletedTask;
    }

    private Task OnPanned( SvgChartPannedEventArgs eventArgs )
    {
        lastEvent = $"Panned viewport X {eventArgs.Viewport.XMin:0.##}-{eventArgs.Viewport.XMax:0.##}, Y {eventArgs.Viewport.YMin:0.##}-{eventArgs.Viewport.YMax:0.##}";

        return Task.CompletedTask;
    }

    private sealed class StorePerformance
    {
        public double Traffic { get; set; }

        public double Sales { get; set; }
    }
}

Initial viewport

Start a chart already zoomed to a configured viewport and control it from a chart reference.
1 series, 10 categories.CPU utilizationInitial viewport configured declaratively02040608010000:0000:0500:1000:1500:2000:2500:3000:3500:4000:45
<Div Flex="Flex.Row" Gap="Gap.Is2" Margin="Margin.Is3.FromBottom">
    <Button Color="Color.Primary" Outline Clicked="@ZoomIn">Zoom in</Button>
    <Button Color="Color.Light" Clicked="@ResetZoom">Reset</Button>
</Div>

<SvgLineChart @ref="chart"
              TItem="CpuSample"
              Items="@samples"
              Options="@options">
    <SvgChartTitle Title='@("CPU utilization")' Subtitle='@("Initial viewport configured declaratively")' />
    <SvgChartTooltip Enabled />
    <SvgChartZoom Enabled
                  Mode="SvgChartZoomMode.X"
                  MaxZoom="12"
                  Viewport="@viewport"
                  ViewportChanged="@OnViewportChanged" />
    <SvgChartCategoryAxis Value="@( item => item.Minute )" />
    <SvgChartValueAxis BeginAtZero TickCount="6" />

    <SvgLineSeries Name="CPU" Value="@( item => item.Value )" Color="Color.Primary" StrokeWidth="3" MarkerRadius="4" />
</SvgLineChart>
@code {
    private SvgLineChart<CpuSample> chart;

    private SvgChartViewport viewport = new()
    {
        XMin = 2,
        XMax = 7,
    };

    private readonly SvgChartOptions options = new()
    {
        Height = 360,
        Legend = new() { Visible = false },
        XAxis = new()
        {
            GridLines = new() { Visible = true },
        },
    };

    private readonly List<CpuSample> samples =
    [
        new() { Minute = "00:00", Value = 45 },
        new() { Minute = "00:05", Value = 52 },
        new() { Minute = "00:10", Value = 49 },
        new() { Minute = "00:15", Value = 64 },
        new() { Minute = "00:20", Value = 72 },
        new() { Minute = "00:25", Value = 68 },
        new() { Minute = "00:30", Value = 77 },
        new() { Minute = "00:35", Value = 70 },
        new() { Minute = "00:40", Value = 74 },
        new() { Minute = "00:45", Value = 82 },
    ];

    private async Task ZoomIn()
    {
        if ( chart is not null )
            await chart.ZoomIn();
    }

    private async Task ResetZoom()
    {
        if ( chart is not null )
            await chart.ResetZoom();
    }

    private Task OnViewportChanged( SvgChartViewport changedViewport )
    {
        viewport = changedViewport;

        return Task.CompletedTask;
    }

    private sealed class CpuSample
    {
        public string Minute { get; set; }

        public double Value { get; set; }
    }
}

API

See the API reference for the parameters, events, methods, and related types available to the components covered on this page.

On this page