apexcharts / Blazor-ApexCharts

A blazor wrapper for ApexCharts.js
https://apexcharts.github.io/Blazor-ApexCharts
MIT License
749 stars 88 forks source link

How do I get the Annotation points to be set based on one of the value of X-axis and Y-axis? #477

Open Amirularif opened 2 weeks ago

Amirularif commented 2 weeks ago

I am working on a Blazor Project Web App (Hybrid). Currently, I'm trying to create a stats card that has a graph on it. To make it more nicer, I wanted to add an annotation point on the graph to look something like this:

image

But, currently this annotation point was achieved based on X=60, Y=35 value. what I want to achieve is more like I have a set of days on the X-axis from Monday to Sunday, and a set of waterflow values on the Y-axis. So I create a function to get the day with the highest waterflow and I want to set annotation point on that day. Currently this is the method I'm using to try and achieve this. However, eventhough I am getting the day with the highest waterflow, I can't map that value to the X and Y value. I look for tutorials online, but there isn't anything helpful so I'm reaching out here. Is there a way around this?

<ApexChart TItem="WeekData"
           Options="options">

    <ApexPointSeries TItem="WeekData"
                     Items="Data"
                     SeriesType="SeriesType.Area"
                     XValue="e => e.Days"
                     YValue="e => e.Waterflow"/>

</ApexChart>

@code {

    private List<WeekData> Data { get; set; } = new();

    private ApexChartOptions<WeekData> options = new ApexChartOptions<WeekData>();

    protected override void OnInitialized()
    {
        options.Yaxis = [new YAxis { Min=0, Show = false, },];

        options.Xaxis = new XAxis 
        { 
            Type = XAxisType.Category,

            Categories = Data.Select(d =>d.Days).ToList(),

            Labels = new XAxisLabels { Show = false }, 

            AxisTicks = new AxisTicks { Show =  false},
        };

        options.Grid = new Grid { Show = false };

        options.Tooltip = new Tooltip { Enabled = false };

        options.Legend = new Legend
        {
            Show = false,   
        };

        options.Stroke = new Stroke
        {
            Curve = Curve.Smooth
        };

        options.Chart = new Chart
        {
            Height = "105%",
            Width = "110px",
            //FontFamily = "Roboto Medium",
            ParentHeightOffset = 0,
            Toolbar = new Toolbar {Show = false},
            Zoom = new Zoom {Enabled = false},
        };

        options.Colors = new List<string> { "#6C79F4" };

        options.Fill = new Fill
        {
            Type = new List<FillType> { FillType.Gradient },
            Gradient = new FillGradient
            {
                ShadeIntensity = 0.5,
                OpacityFrom = 0.7,
                OpacityTo = 0.2,
                Type = GradientType.Vertical,

            }
        };

        Data.Add(new WeekData { Days = "Mon", Waterflow = 15 });
        Data.Add(new WeekData { Days = "Tue", Waterflow = 10 });
        Data.Add(new WeekData { Days = "Wed", Waterflow = 25 });
        Data.Add(new WeekData { Days = "Thu", Waterflow = 20 });
        Data.Add(new WeekData { Days = "Fri", Waterflow = 35 });
        Data.Add(new WeekData { Days = "Sat", Waterflow = 30 });
        Data.Add(new WeekData { Days = "Sun", Waterflow = 32 });

        SetAnnotationsBasedOnData();

    }

    public class WeekData
    {
        public string Days { get; set; }

        public int Waterflow { get; set; }
    }

    private void SetAnnotationsBasedOnData()
    {
        var maxDataPoint = Data.OrderByDescending(d => d.Waterflow).First();

        Console.WriteLine($"Setting annotation at X: {maxDataPoint.Days}, Y: {maxDataPoint.Waterflow}");

        options.Annotations = new Annotations
            {
                Points = new List<AnnotationsPoint>
            {
                new AnnotationsPoint
                {
                    //X = maxDataPoint.Days,  I want to use this instead
                    //Y = maxDataPoint.Waterflow, and this

                    X = 60, //this is the current method being used to achieve the image
                    Y = 35, //this is the current method being used to achieve the image

                    Label = new Label
                    {
                        Text = $"↗ {maxDataPoint.Waterflow}%",
                        BorderColor = "transparent",
                        Style = new Style
                        {
                            Background = "transparent",
                            Color = "#6C79F4",
                            FontFamily = "Roboto Medium",
                        }
                    },
                    Marker = new AnnotationMarker
                    {
                        FillColor = "#6C79F4",
                        StrokeColor = "white",
                        Size = 5,
                    }
                }

            }
        };

    }
}