RadzenCategoryAxis min/max gives error on future dates

Hello,

I'm trying to make a trend chart where the amount of searches done on a webpage is set against the date the search happened. I want the user to be able to select the daterange they want to see the trend line for. I also want to make sure that the selected daterange is valid. All of this works, but stops working when I'm trying to set a min and max to the CategoryAxis. I can select any daterange except for a daterange that lies in the future? The Chart and DatePicker code is as follows:

<RadzenCard>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">From</RadzenText>
                <RadzenDatePicker @bind-Value="startDay" Change=@(args => OnManualDateChange(args, null, "MM/dd/yyyy")) Class="w-100" DateFormat="d" />
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">To</RadzenText>
                <RadzenDatePicker @bind-Value="endDay" Change=@(args => OnManualDateChange(null, args, "MM/dd/yyyy")) Class="w-100" DateFormat="d" />
            </RadzenCard>
            <RadzenCard Class="w-100 mb-4" Style="display: flex; align-items: center; gap: 0.5rem">
                <RadzenCheckBox @bind-Value="@trend" Name="trend"></RadzenCheckBox>
                <RadzenLabel Text="Trend" For="trend" Style="margin-right: 1rem;" Class="rz-color-danger-dark" />
                <RadzenCheckBox @bind-Value="@median" Name="median"></RadzenCheckBox>
                <RadzenLabel Text="Median" For="median" Style="margin-right: 1rem;" Class="rz-color-success-dark" />
                <RadzenCheckBox @bind-Value="@mean" Name="mean"></RadzenCheckBox>
                <RadzenLabel Text="Mean" For="mean" Style="margin-right: 1rem;" Class="rz-color-info-dark" />
                <RadzenCheckBox @bind-Value="@mode" Name="mode"></RadzenCheckBox>
                <RadzenLabel Text="Mode" For="mode" Class="rz-color-warning-darker" />
            </RadzenCard>
            <RadzenChart>
                @if (_recordsInRange.Count() > 1)
                {
                    <RadzenLineSeries Smooth="true" Data="@_recordsInRange" CategoryProperty="DateTime" Title="Search Count per Date" ValueProperty="SearchCount" RenderingOrder="1">
                        <RadzenSeriesTrendLine Visible="@trend" Stroke="var(--rz-danger-dark)" LineType="LineType.Dashed" />
                        <RadzenSeriesMedianLine Visible="@median" Stroke="var(--rz-success-dark)" LineType="LineType.Dotted" />
                        <RadzenSeriesMeanLine Visible="@mean" Stroke="var(--rz-info-dark)" LineType="LineType.Dotted" />
                        <RadzenSeriesModeLine Visible="@mode" Stroke="var(--rz-warning-darker)" LineType="LineType.Dotted" />
                    </RadzenLineSeries>
                }
                else
                {
                    <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">There is not enough data available within the selected timeframe. Please select a timeframe that contains more data.</RadzenText>
                }
                <RadzenCategoryAxis Padding="20" Min="_startDay" Max="_endDay" >
                    <RadzenAxisTitle Text="Date" />
                </RadzenCategoryAxis>
                <RadzenValueAxis>
                    <RadzenGridLines Visible="true" />
                    <RadzenAxisTitle Text="Amount of Searches" />
                </RadzenValueAxis>
            </RadzenChart>

And the code to change the date:

void OnDateChanged(DateTime? from, DateTime? to, string format)
    {
        startDay = from ?? startDay;
        endDay = to ?? endDay;
        checkDateRangeValid(startDay, endDay);
        filterRecords(startDay, endDay);
        setMinMaxRangeForChart(startDay, endDay);
    }

    void checkDateRangeValid(DateTime from, DateTime to)
    {
        if (from >= to)
        {
            endDay = startDay.AddDays(1);
        }
        if (to <= from)
        {
            startDay = endDay.AddDays(-1);
        }
    }

    void setMinMaxRangeForChart(DateTime from, DateTime to)
    {
        _startDay = from;
        _endDay = to;
    }

    void filterRecords(DateTime from, DateTime to)
    {
        _recordsInRange = _records.Where(record => record.DateTime >= from && record.DateTime <= to);
    }

The error we receive is as follows:

Hi @Avugt,

Can you paste some runnable reproduction of this problem? I couldn't reproduce it in my tests. Here is what I tried.

                <RadzenChart>
                    <RadzenLineSeries Data="@revenue2019" CategoryProperty="Date" Title="2019" LineType="LineType.Dashed" ValueProperty="Revenue">
                        <RadzenMarkers MarkerType="MarkerType.Square" />
                    </RadzenLineSeries>
                    <RadzenLineSeries Data="@revenue2020" CategoryProperty="Date" Title="2020" ValueProperty="Revenue">
                        <RadzenMarkers MarkerType="MarkerType.Circle" />
                        <RadzenSeriesDataLabels Visible="@showDataLabels" />
                    </RadzenLineSeries>
                    <RadzenCategoryAxis Padding="20" Formatter="@FormatAsMonth" Min="@DateTime.Parse("2018-02-01")" />
                    <RadzenValueAxis Formatter="@FormatAsUSD">
                        <RadzenGridLines Visible="true" />
                        <RadzenAxisTitle Text="Revenue in USD" />
                    </RadzenValueAxis>
                </RadzenChart>
@code {
  class DataItem
    {
        public DateTime Date { get; set; }
        public double Revenue { get; set; }
    }

    string FormatAsUSD(object value)
    {
        return ((double)value).ToString("C0", CultureInfo.CreateSpecificCulture("en-US"));
    }

    string FormatAsMonth(object value)
    {
        if (value != null)
        {
            return Convert.ToDateTime(value).ToString("MMM/yyyy");
        }

        return string.Empty;
    }

    DataItem[] revenue2019 = new DataItem[] {
        new DataItem
        {
            Date = DateTime.Parse("2019-01-01"),
            Revenue = 234000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-02-01"),
            Revenue = 269000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-03-01"),
            Revenue = 233000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-04-01"),
            Revenue = 244000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-05-01"),
            Revenue = 214000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-06-01"),
            Revenue = 253000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-07-01"),
            Revenue = 274000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-08-01"),
            Revenue = 284000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-09-01"),
            Revenue = 273000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-10-01"),
            Revenue = 282000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-11-01"),
            Revenue = 289000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-12-01"),
            Revenue = 294000
        }
    };

    DataItem[] revenue2020 = new DataItem[] {
        new DataItem
        {
            Date = DateTime.Parse("2019-01-01"),
            Revenue = 334000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-02-01"),
            Revenue = 369000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-03-01"),
            Revenue = 333000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-04-01"),
            Revenue = 344000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-05-01"),
            Revenue = 314000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-06-01"),
            Revenue = 353000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-07-01"),
            Revenue = 374000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-08-01"),
            Revenue = 384000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-09-01"),
            Revenue = 373000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-10-01"),
            Revenue = 382000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-11-01"),
            Revenue = 389000
        },
        new DataItem
        {
            Date = DateTime.Parse("2019-12-01"),
            Revenue = 394000
        }
    };
}

Hi!

I tried to make a runnable reproduction for you, but in this reproduction it throws the 'cannot convert DateTime to Double' error right away.

Here is what I made:

@page "/test"
@using System.Globalization
@using Radzen
@using Radzen.Blazor
@using Namespace.Helpers

<div class="container my-5">
    <div class="row">
        <div class="col">
            <RadzenCard>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">From</RadzenText>
                <RadzenDatePicker @bind-Value="startDay" Change=@(args => OnDateChanged(args, null)) Class="w-100" DateFormat="MM/dd/yyyy" />
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">To</RadzenText>
                <RadzenDatePicker @bind-Value="endDay" Change=@(args => OnDateChanged(null, args)) Class="w-100" DateFormat="MM/dd/yyyy" />
            </RadzenCard>
                        <RadzenCard Class="w-100 mb-4" Style="display: flex; align-items: center; gap: 0.5rem">
            <RadzenCheckBox @bind-Value="@trend" Name="trend"></RadzenCheckBox>
            <RadzenLabel Text="Trend" For="trend" Style="margin-right: 1rem;" Class="rz-color-danger-dark" />
            <RadzenCheckBox @bind-Value="@median" Name="median"></RadzenCheckBox>
            <RadzenLabel Text="Median" For="median" Style="margin-right: 1rem;" Class="rz-color-success-dark" />
            <RadzenCheckBox @bind-Value="@mean" Name="mean"></RadzenCheckBox>
            <RadzenLabel Text="Mean" For="mean" Style="margin-right: 1rem;" Class="rz-color-info-dark" />
            <RadzenCheckBox @bind-Value="@mode" Name="mode"></RadzenCheckBox>
            <RadzenLabel Text="Mode" For="mode" Class="rz-color-warning-darker" />
            </RadzenCard>
            <RadzenChart>
            @if (_recordsInRange.Count() > 1)
            {
            <RadzenLineSeries Smooth="true" Data="@_recordsInRange" CategoryProperty="DateTime" Title="Search Count per Date" ValueProperty="SearchCount" RenderingOrder="1">
            <RadzenSeriesTrendLine Visible="@trend" Stroke="var(--rz-danger-dark)" LineType="LineType.Dashed" />
            <RadzenSeriesMedianLine Visible="@median" Stroke="var(--rz-success-dark)" LineType="LineType.Dotted" />
            <RadzenSeriesMeanLine Visible="@mean" Stroke="var(--rz-info-dark)" LineType="LineType.Dotted" />
            <RadzenSeriesModeLine Visible="@mode" Stroke="var(--rz-warning-darker)" LineType="LineType.Dotted" />
            </RadzenLineSeries>
            }
            else
            {
            <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">There is not enough data available within the selected timeframe. Please select a timeframe that contains more data.</RadzenText>
            }
            <RadzenCategoryAxis Padding="20" Formatter="@toFormattedString" Min="@_startDay" Max="@_endDay">
            <RadzenAxisTitle Text="Date" />
            </RadzenCategoryAxis>
            <RadzenValueAxis>
            <RadzenGridLines Visible="true" />
            <RadzenAxisTitle Text="Amount of Searches" />
            </RadzenValueAxis>
            </RadzenChart>
        </div>
    </div>
</div>

@code {
    bool trend = true;
    bool median = false;
    bool mean = false;
    bool mode = false;

    DateTime now = DateTime.Today;
    DateTime startDay = DateModificationHelper.FirstDayOfWeek(DateTime.Today, DayOfWeek.Monday);
    DateTime endDay = DateModificationHelper.LastDayOfWeek(DateTime.Today, DayOfWeek.Monday);
    DateTime _startDay;
    DateTime _endDay;

    IEnumerable<DataItem> _recordsInRange;

    class DataItem
    {
        public DateTime? DateTime { get; set; }
        public int? SearchCount { get; set; }
    }

    void OnDateChanged(DateTime? from, DateTime? to)
    {
        startDay = from ?? startDay;
        endDay = to ?? endDay;
        checkDateRangeValid(startDay, endDay);
        filterRecords(startDay, endDay);
        setMinMaxRangeForChart(startDay, endDay);
    }

    void checkDateRangeValid(DateTime from, DateTime to)
    {
        if (from >= to)
        {
            endDay = startDay.AddDays(1);
        }
        if (to <= from)
        {
            startDay = endDay.AddDays(-1);
        }
    }

    void setMinMaxRangeForChart(DateTime from, DateTime to)
    {
        _startDay = from;
        _endDay = to;
    }

    void filterRecords(DateTime from, DateTime to)
    {
        _recordsInRange = _records.Where(record => record.DateTime >= from && record.DateTime <= to);
    }

    string toFormattedString(object value)
    {
        if (value != null)
        {
            return Convert.ToDateTime(value).ToString("MM/dd/yyyy");
        }
        return string.Empty;
    }

    protected override async Task OnInitializedAsync()
    {
        _recordsInRange = _records;
        filterRecords(startDay, endDay);
        _startDay = startDay;
        _endDay = endDay;
    }

    DataItem[] _records = new DataItem[] {
        new DataItem
        {
            DateTime = DateTime.Parse("2019-01-01"),
            SearchCount = 234000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2019-02-01"),
            SearchCount = 269000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2020-03-01"),
            SearchCount = 233000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2021-04-01"),
            SearchCount = 244000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2022-05-01"),
            SearchCount = 214000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2019-06-01"),
            SearchCount = 253000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2019-07-01"),
            SearchCount = 274000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2020-08-01"),
            SearchCount = 284000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2021-09-01"),
            SearchCount = 273000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2022-10-01"),
            SearchCount = 282000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2019-11-01"),
            SearchCount = 289000
        },
        new DataItem
        {
            DateTime = DateTime.Parse("2020-12-01"),
            SearchCount = 294000
        }
    };

}

With the helper class:

using System.Globalization;

namespace Namespace.Helpers
{
    public static class DateModificationHelper
    {
       
        public static DateTime FirstDayOfWeek(this DateTime dt, DayOfWeek startOfWeek)
        {
            int diff = dt.DayOfWeek - startOfWeek;
            if (diff < 0)
            {
                diff += 7;
            }

            return dt.AddDays(-1 * diff).Date;
        }
        public static DateTime FirstDayOfMonth(this DateTime dt)
        {
            return new DateTime(dt.Year, dt.Month, 1);
        }
        public static DateTime LastDayOfMonth(this DateTime dt)
        {
            return new DateTime(dt.Year, dt.Month, 1).AddMonths(1).AddDays(-1);
        }
        public static DateTime LastDayOfWeek(this DateTime dt, DayOfWeek startOfWeek)
        {
            return dt.FirstDayOfWeek(startOfWeek).AddDays(6);
        }
        public static DateTime FirstDayOfYear(this DateTime dt)
        {
            return new DateTime(dt.Year, 1, 1);
        }
        public static DateTime LastDayOfYear(this DateTime dt)
        {
            return new DateTime(dt.Year, 12, 31);
        }
    }
}

I hope this could help, ty.