Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Real-time chart losing it's drawn lines #509

Open
horrorhound opened this issue Sep 12, 2024 · 2 comments
Open

Real-time chart losing it's drawn lines #509

horrorhound opened this issue Sep 12, 2024 · 2 comments

Comments

@horrorhound
Copy link

horrorhound commented Sep 12, 2024

I'll try and get a sample project for this together to demo this but for now here is the issue:

Razor page with ApexChart injects a Blazor Server Service
Service is Singleton Service which Raises Events with a int value.
Razor page accepts the raised event from singleton service
OnEvent Method adds Timestamp h:mm:ss format to XValue and the int value to YValue
If an event executes to "quickly" the lines in the chart disappears.

*Thoughts
Maybe some type of collision in threads so I've tried adding locks and delays in the events.
I *think maybe the chart is trying to re-write data for the same Timestamp value which it just wrote might cause the problem.

  • So I've tried to "buffer" the data and only write the timestamp and value once ever but issue still occurs.
    • Maybe it's when an event executes while drawing the chart lines causes the failure. I
  • Pretty easy to reproduce, I just have to raise events quickly.
  • Application is currently on latest NuGet version and application is .NET 7 Blazor Server
  • I've tried and tried adding different Task Delays, waits, locks etc but still haven't come up valid work-around.

To recover I have to re-load the page or call RenderAsync(). Once the lines disappear I can still write to the Chart and the tool tips update and new XValues are added, but the YValue lines fail to ever display until I perform a recovery step.

```

<ApexChart @ref=_apexChart TItem="ChartDataPoint"
Title="Checkins"
Options=_apexOptions>

<ApexPointSeries TItem="ChartDataPoint"
Name="Checkins"
SeriesType="SeriesType.Line"
XValue="@(e => e.Timestamp.ToString("h:mm:ss"))"
YValue="@(e => e.Value)"
OrderBy="e=>e.X"
ShowDataLabels="false" />

private class ChartDataPoint
{
public DateTime Timestamp { get; set; }
public int Value { get; set; }
}
private ApexChart _apexChart;
private ApexChartOptions _apexOptions = new ApexChartOptions
{
Colors = new List { "rgba(119,107,231,1)" },
Theme = new Theme
{

    Mode = Mode.Dark,
    Palette = PaletteType.Palette10  // Palette doesn't seem to change at all.
  },
  Chart = new Chart
  {
    Animations = new Animations
    {
      Enabled = true,
      Easing = Easing.Linear,
      DynamicAnimation = new DynamicAnimation
      {
        Speed = 950
      }
    },
    Height = 350,
    Toolbar = new Toolbar
    {
      Show = false
    },
    Type = ApexCharts.ChartType.Line,
    Background = "rgb(55, 55, 64)",
    Zoom = new Zoom
    {
      Enabled = false
    }
  },
  Yaxis = new()
  {
      new()
      {
          TickAmount = 10,
          Min = 0,
          Max = 50
      }
  },
  Xaxis = new()
  {
    Range = 10 // number of datapoints to display.
  },
  Stroke = new Stroke { Curve = Curve.Straight },
};

private void HandleOnChanged
{
await _apexChart.AppendDataAsync(dataToAppend);
}


@horrorhound horrorhound changed the title Real-time chart losing it's drawn lines in chart Real-time chart losing it's drawn lines Sep 12, 2024
@joadan
Copy link
Member

joadan commented Oct 26, 2024

Sorry but I would recomend with a simple example and try to reproduce.
Have you looked at the sample at https://apexcharts.github.io/Blazor-ApexCharts/methods/update-series#realtime

@horrorhound
Copy link
Author

horrorhound commented Oct 27, 2024

Yes, I've seen that and my code works fine also; but the issue is when the XValue already exists and you try and update it. So that's a good idea though; maybe I'll take their sample code and re-create the issue without changing the date on the XValue in their sample.

What I have working at the moment is this...

Event: Queue up the data to be processed by Apexchart; cause processing the data immediately if there's already the same timestamp data on the chart causes failure.

private void HandleStatsChanged(Data.ProductStats productStat)
  {
    Log.Information("Entered HandleStatsChanged...");
    lock (_pendingData)
    {
      var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
      // Append to existing entry or add new one if it doesn't exist
      if (_pendingData.ContainsKey(timestamp))
      {
        _pendingData[timestamp] += 1;
      }
      else
      {
        _pendingData[timestamp] = 1;
      }

      Task.Delay(5);  // Can probably remove
    }
 }

Timer: Update the chart based off a timer event every 3seconds.

private void OnTimerElapsed(object state)
{
  lock (_pendingData)
  {
    // Collect the data accumulated in the last second and append it to the chart
    if (_pendingData.Count > 0)
    {
      var dataToAppend = _pendingData.Select(kvp => new ChartDataPoint
        {
          Timestamp = DateTime.Parse(kvp.Key),
          Value = kvp.Value
        }).ToList();

      // Clear the pending data
      _pendingData.Clear();

      // Update the chart on a different thread
      InvokeAsync(async () =>
      {
        await _apexChart.AppendDataAsync(dataToAppend);
      });
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants