Scatter Chart


The Blazor Scatter Chart component displays data values as vertical bars, making it easy to compare multiple data sets or visualize trends over time.

API Documentation

Chart setup #

Before using any chart demo: install BlazorExpress.ChartJS 1.2.2, load Chart.js 4.4.1, chartjs-plugin-datalabels 2.2.0, and _content/BlazorExpress.ChartJS/blazorexpress.chartjs.js, then add @using BlazorExpress.ChartJS to your chart page or chart folder.

Follow the shared chart setup guide, the .NET 8 WebAssembly guide, or the .NET 8 Web App Server guide. For full chart component guidance and examples, visit chartjs.blazorexpress.com.

How it works #

The Scatter Chart component visualizes individual data points as (X, Y) coordinates, making it ideal for displaying relationships or distributions between two numeric variables.

How to use:
  1. Add the ScatterChart component to your page and set its dimensions (e.g., Width="560", Height="480").
  2. Prepare your chart data by creating one or more ScatterChartDataset objects, each containing a list of ScatterChartDataPoint instances with X and Y values.
  3. Customize the appearance of each dataset using properties like BackgroundColor, BorderColor, and BorderWidth.
  4. Configure chart options using the ScatterChartOptions object as needed.
  5. Initialize the chart in OnAfterRenderAsync by calling scatterChart.InitializeAsync(chartData, scatterChartOptions).
  6. Refer to the demo code below for practical examples of data preparation, dataset customization, and chart initialization.
This demo shows how to set up a scatter chart, bind your data, and customize the chart's appearance to fit your application's needs.
<div style="overflow-x: auto;">
    <ScatterChart @ref="scatterChart" Width="560" Height="480" />
</div>

@code {
    private ScatterChart scatterChart = default!;
    private ScatterChartOptions scatterChartOptions = default!;
    private ChartData chartData = default!;

    private Random random = new();

    protected override void OnInitialized()
    {
        chartData = new ChartData
        {
            Datasets = new()
                {
                    GetRandomRadarChartDataset(0),
                    GetRandomRadarChartDataset(1),
                    GetRandomRadarChartDataset(2)
                }
        };

        scatterChartOptions = new() { };
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await scatterChart.InitializeAsync(chartData, scatterChartOptions);
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    #region Data Preparation

    private ScatterChartDataset GetRandomRadarChartDataset(int recordIndex)
    {
        var c = ChartJsColorExtensions.ToColor(ChartJsColorUtility.CategoricalTwelveColors[recordIndex]);

        return new ScatterChartDataset
        {
            Label = $"Team {recordIndex + 1}",
            Data = GetRandomData(),
            BackgroundColor = ChartJsColorExtensions.ToRgbaString(c), // RGBA
            BorderColor = ChartJsColorExtensions.ToRgbString(c), // RGB
            BorderWidth = 2,
            HoverBorderWidth = 4,
        };
    }

    private List<ScatterChartDataPoint> GetRandomData()
    {
        var data = new List<ScatterChartDataPoint>();
        for (var index = 0; index < 10; index++)
        {
            data.Add(new(random.Next(200), random.Next(200)));
        }

        return data;
    }

    #endregion Data Preparation
}

Dynamic data #

The Scatter Chart component supports dynamic data updates, allowing you to add, remove, or modify data points and datasets at runtime. This is useful for visualizing real-time data or enabling interactive data exploration.

How to use:
  1. Add the ScatterChart component to your page and set its Width and Height as needed.
  2. Prepare your chart data using one or more ScatterChartDataset objects, each containing a list of ScatterChartDataPoint (with X and Y values).
  3. Implement methods to update your data dynamically, such as adding new points, randomizing values, or modifying existing datasets.
  4. After updating the data, call scatterChart.UpdateAsync(chartData, scatterChartOptions) to refresh the chart and reflect the changes.
  5. Refer to the demo code below for practical examples of dynamic data manipulation and chart updates in a Blazor application.
This demo demonstrates how to work with dynamic data in a scatter chart, enabling interactive and real-time data visualizations in your Blazor projects.
?
?<ScatterChart @ref="scatterChart" />


<div class="mt-5">
    <Button Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="RandomizeAsync"> Randomize </Button>
    <Button Color="ButtonColor.Link" Size="ButtonSize.Small" @onclick="AddDatasetAsync"> Add Dataset </Button>
    <Button Color="ButtonColor.Info" Size="ButtonSize.Small" @onclick="AddDataAsync"> Add Data </Button>
    <Button Color="ButtonColor.Success" Size="ButtonSize.Small" @onclick="ShowHorizontalLineChartAsync"> Horizontal Line Chart </Button>
    <Button Color="ButtonColor.Warning" Size="ButtonSize.Small" @onclick="ShowVerticalLineChartAsync"> Vertical Line Chart </Button>
</div>

@code {
    private ScatterChart scatterChart = default!;
    private ScatterChartOptions scatterChartOptions = default!;
    private ChartData chartData = default!;

    private int datasetsCount;
    private int dataLabelsCount;

    private Random random = new();

    protected override void OnInitialized()
    {
        chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) };
        scatterChartOptions = new()
        {
            Responsive = true,
            Interaction = new Interaction { Mode = InteractionMode.Index },
        };
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await scatterChart.InitializeAsync(chartData, scatterChartOptions);
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    private async Task RandomizeAsync()
    {
        if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return;

        var newDatasets = new List<IChartDataset>();

        foreach (var dataset in chartData.Datasets)
        {
            if (dataset is ScatterChartDataset scatterChartDataset
                && scatterChartDataset is not null
                && scatterChartDataset.Data is not null)
            {
                var count = scatterChartDataset.Data.Count;

                var newData = new List<ScatterChartDataPoint>();
                for (var i = 0; i < count; i++)
                {
                    newData.Add(new(random.Next(200), random.Next(200)));
                }

                scatterChartDataset.Data = newData;
                newDatasets.Add(scatterChartDataset);
            }
        }

        chartData.Datasets = newDatasets;

        await scatterChart.UpdateAsync(chartData, scatterChartOptions);
    }

    private async Task AddDatasetAsync()
    {
        if (datasetsCount >= 12)
            return;

        if (chartData is null || chartData.Datasets is null) return;

        var chartDataset = GetRandomScatterChartDataset();
        chartData = await scatterChart.AddDatasetAsync(chartData, chartDataset, scatterChartOptions);
    }

    private async Task AddDataAsync()
    {
        if (chartData is null || chartData.Datasets is null)
            return;

        var data = new List<IChartDatasetData>();
        foreach (var dataset in chartData.Datasets)
        {
            if (dataset is ScatterChartDataset scatterChartDataset)
                data.Add(new ScatterChartDatasetData(scatterChartDataset.Label, new ScatterChartDataPoint(random.Next(200), random.Next(200))));
        }

        chartData = await scatterChart.AddDataAsync(chartData, GetNextDataLabel(), data);
    }

    private async Task ShowHorizontalLineChartAsync()
    {
        scatterChartOptions.IndexAxis = "y";
        await scatterChart.UpdateAsync(chartData, scatterChartOptions);
    }

    private async Task ShowVerticalLineChartAsync()
    {
        scatterChartOptions.IndexAxis = "x";
        await scatterChart.UpdateAsync(chartData, scatterChartOptions);
    }

    #region Data Preparation

    private List<IChartDataset> GetDefaultDataSets(int numberOfDatasets)
    {
        var datasets = new List<IChartDataset>();

        for (var index = 0; index < numberOfDatasets; index++)
        {
            datasets.Add(GetRandomScatterChartDataset());
        }

        return datasets;
    }

    private ScatterChartDataset GetRandomScatterChartDataset()
    {
        var c = ChartJsColorExtensions.ToColor(ChartJsColorUtility.CategoricalTwelveColors[datasetsCount]);

        datasetsCount += 1;

        return new ScatterChartDataset
        {
            Label = $"Team {datasetsCount}",
            Data = GetRandomData(),
            BackgroundColor = ChartJsColorExtensions.ToRgbaString(c), // RGBA
            BorderColor = ChartJsColorExtensions.ToRgbString(c), // RGB
            BorderWidth = 2,
            Fill = true,
            HoverBorderWidth = 4,
            PointHoverRadius = new List<double> { 6 },
        };
    }

    private List<ScatterChartDataPoint> GetRandomData()
    {
        var data = new List<ScatterChartDataPoint>();
        for (var index = 0; index < dataLabelsCount; index++)
        {
            data.Add(new ScatterChartDataPoint(random.Next(200), random.Next(200)));
        }

        return data;
    }

    private List<string> GetDefaultDataLabels(int numberOfLabels)
    {
        var labels = new List<string>();
        for (var index = 0; index < numberOfLabels; index++)
        {
            labels.Add(GetNextDataLabel());
        }

        return labels;
    }

    private string GetNextDataLabel()
    {
        dataLabelsCount += 1;
        return $"Day {dataLabelsCount}";
    }

    #endregion Data Preparation

}
DO YOU KNOW?
This demo website is built using the BlazorExpress.Bulma library and published on the Azure Web App. See our source code on GitHub.