Skip to content

Synchronized Charts: Line Chart (Datetime) + Range Bar (Date Range) not syncing properly #647

@davideTES

Description

@davideTES

Context

I'm attempting to implement the "Synchronized Charts" feature as described in the Blazor-ApexCharts documentation at: https://apexcharts.github.io/Blazor-ApexCharts/features/syncronized

Problem Statement

I need to synchronize charts of different types:

  1. Line Chart with XAxisType.Datetime displaying aggregated time-series data
  2. Range Bar Chart with date range visualization for projects/activities on the same temporal axis
    Currently, the charts are not maintaining synchronization when interacting with them (zoom, pan, selection).

Current Behavior

• Both charts have the same Chart.Group = "SyncGroup" assigned
• They share the same time-base (last 100 days)
• Interactions on one chart do not synchronize the other

@page "/weather"
@rendermode InteractiveServer
@using global::ApexCharts

<PageTitle>Blazor-ApexCharts</PageTitle>

<div id="synced-charts" class="charts-container">
    <!-- Line Chart: Value -->
    <ApexChart TItem="TimeSeries"
               Title="Value"
               Options=options1
               Height="150"
               XAxisType="XAxisType.Datetime">

        <ApexPointSeries TItem="TimeSeries"
                         Items="data"
                         Name="Value"
                         SeriesType="SeriesType.Line"
                         XValue="@(e => e.Date)"
                         YAggregate="@(e => e.Sum(e => e.Value))"
                         OrderBy="e=>e.X"
                         Stroke="@(new SeriesStroke { Width = 2, Color="#1F15E5"})" />
    </ApexChart>

    <!-- Area Chart: Quantity -->
    <ApexChart TItem="TimeSeries"
               Title="Quantity"
               Options=options2
               Height="150"
               XAxisType="XAxisType.Datetime">

        <ApexPointSeries TItem="TimeSeries"
                         Items="data"
                         Name="Quantity"
                         SeriesType="SeriesType.Area"
                         XValue="@(e => e.Date)"
                         YValue="@(e => e.Quantity)"
                         OrderBy="e=>e.X"
                         Stroke="@(new SeriesStroke { Width = 2, Color="#E51C15"})" />
    </ApexChart>

    <!-- Range Bar Chart: Projects Timeline -->
    <ApexChart TItem="Project" 
               Title="Projects Timeline"
               Options="options3" 
               XAxisType="XAxisType.Datetime">
        <ApexRangeSeries TItem="Project"
                         Items="projects"
                         XValue="@(e => e.Name)"
                         YMinValue="@(e =>e.StartDate.ToUnixTimeMilliseconds())"
                         YMaxValue="@(e =>e.EndDate.ToUnixTimeMilliseconds())" />
    </ApexChart>
</div>
    
@code {
    private List<TimeSeries> data { get; set; } = new List<TimeSeries>();
    private List<Project> projects = new List<Project>();
    private ApexChartOptions<TimeSeries> options1 = new();
    private ApexChartOptions<TimeSeries> options2 = new();
    private ApexChartOptions<Project> options3 = new();

    protected override void OnInitialized()
    {
        const string groupName = "SyncGroup";
        const int YAxisMinWidth = 40;

        var generator = new FakeDataGenerator();
        var startDate = DateTime.Now.AddDays(-100);
        var endDate = DateTime.Now;

        data = generator.GenerateTimeSeries(100, startDate);
        projects = generator.GenerateProjects(startDate, endDate);

        // Line Chart Options
        options1.Chart = new Chart { Group = groupName };
        options1.Yaxis = new List<YAxis> { new YAxis {
                Labels = new YAxisLabels { MinWidth = YAxisMinWidth}}
        };

        // Area Chart Options
        options2.Chart = new Chart { Group = groupName };
        options2.Yaxis = new List<YAxis> { new YAxis
            {
                Labels = new YAxisLabels { MinWidth = YAxisMinWidth}}
        };
        options2.Chart.Toolbar = new Toolbar { Show = false };
        options2.Xaxis = new XAxis { TickPlacement = TickPlacement.On };

        // Range Bar Chart Options
        options3 = new ApexChartOptions<Project>()
        {
            PlotOptions = new PlotOptions()
            {
                Bar = new PlotOptionsBar { Horizontal = true }
            },
            Chart = new Chart { Group = groupName }
        };
    }

    private class FakeDataGenerator
    {
        private readonly Random random = new Random();

        public List<TimeSeries> GenerateTimeSeries(int numberOfPoints, DateTime startDate)
        {
            var result = new List<TimeSeries>();
            for (int i = 0; i < numberOfPoints; i++)
            {
                var date = startDate.AddDays(i);
                result.Add(new TimeSeries
                {
                    Date = date,
                    Value = random.Next(10, 100),
                    Quantity = random.Next(5, 50)
                });
            }
            return result;
        }

        public List<Project> GenerateProjects(DateTime startDate, DateTime endDate)
        {
            var projects = new List<Project>();
            var currentDate = startDate;

            while (currentDate < endDate)
            {
                var projectDuration = random.Next(5, 20);
                var projectEnd = currentDate.AddDays(projectDuration);

                if (projectEnd > endDate)
                    projectEnd = endDate;

                projects.Add(new Project
                {
                    Name = $"Project {projects.Count + 1}",
                    StartDate = currentDate,
                    EndDate = projectEnd
                });

                currentDate = projectEnd.AddDays(random.Next(1, 5));
            }

            return projects;
        }
    }

    private class TimeSeries
    {
        public DateTime Date { get; set; }
        public int Value { get; set; }
        public int Quantity { get; set; }
    }

    private class Project
    {
        public string Name { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
    }
}

<style>
    .charts-container {
        display: flex;
        flex-direction: column;
        gap: 2rem;
    }
</style>
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions