Issue with Missing Data Points in Kendo Chart Line Series

0 Answers 10 Views
Chart
S M Rahiyan
Top achievements
Rank 1
S M Rahiyan asked on 29 Apr 2024, 01:41 AM | edited on 29 Apr 2024, 01:45 AM

Description

Hello Telerik Community,

I'm encountering an issue with my Kendo Chart implementation where certain data points are not displaying on the line series, despite being present in the dataset. Here's a breakdown of the problem and my current setup:

Problem 

- Some data points, specifically those corresponding to the dates November 27 and November 29, are not showing up on the line chart.
- However, these dates are appearing correctly in the category legend.

Setup

- I'm using Kendo Chart to visualize historical pool data.
- Data is fetched from a database and processed in the controller before being passed to the Razor view for rendering.
- Each manufacturer's data is plotted on the chart as separate line series, with the x-axis representing dates and the y-axis representing weight.

Relevant Code

Controller Code: I've provided the relevant controller code responsible for fetching and processing the data.
Razor View Code: Similarly, I've included the Razor view code where the Kendo Chart is defined and configured.

Expected Outcome

- I expect the line chart to display all data points, including those for November 27 and November 29, for each manufacturer.

Steps Taken

- I've checked the data in the controller, and it seems that all data points are correctly fetched from the database.
- I've inspected the generated HTML for the chart and confirmed that the missing data points are indeed not being rendered.

Request for Assistance

- Could you please review my setup and help me identify any potential issues causing the missing data points?
- Additionally, if you have any suggestions for troubleshooting or debugging this issue further, I would greatly appreciate it.

Additional Information

Framework: ASP.NET MVC- Browser: Chrome, Edge

Thank you in advance for your assistance!


public ActionResult ChartTMS(DateTime? fromDate, DateTime? toDate, string unit = "gm")
        {
            fromDate = fromDate?.Date;
            toDate = toDate.HasValue ? toDate.Value.Date.AddDays(1).AddTicks(-1) : DateTime.Today;
 
            if (!fromDate.HasValue || !toDate.HasValue)
            {
                fromDate = DateTime.Today.AddDays(-6);
                toDate = DateTime.Today;
            }
 
            var allMeasurements = (
                from m in db.Target_Measurement_History.AsNoTracking()
                where m.Measurement_Record_Date >= fromDate.Value && m.Measurement_Record_Date <= toDate.Value
&& m.Target_Lot_Profile != null
&& m.Target_Lot_Profile.Target_Item != null
&& m.Target_Lot_Profile.Target_Item.Target_Manufacturer != null
                select new MeasurementDataViewModel
                {
                    Measurement_Record_Date = m.Measurement_Record_Date,
                    Pt_Remaining_Gms = m.Pt_Remaining_Gms,
                    Ru_Remaining_Gms = m.Ru_Remaining_Gms,
                    Manufacturer = m.Target_Lot_Profile.Target_Item.Target_Manufacturer,
                }).ToList();
 
            var manufacturers = allMeasurements.Select(m => m.Manufacturer).Distinct();
            var colorMap = new Dictionary<string, string>();
            Random rand = new Random();
 
            foreach (var manufacturer in manufacturers)
            {
                colorMap[manufacturer] = $"#{rand.Next(0x1000000):X6}";
            }
 
            var groupedData = allMeasurements
                .GroupBy(m => new { m.Measurement_Record_Date.Date, m.Manufacturer })
                .Select(group => new MeasurementDataViewModel
                {
                    Measurement_Record_Date = group.Key.Date,
                    Pt_Remaining_Gms = group.Sum(item => item.Pt_Remaining_Gms),
                    Ru_Remaining_Gms = group.Sum(item => item.Ru_Remaining_Gms),
                    Manufacturer = group.Key.Manufacturer,
                    Color = colorMap[group.Key.Manufacturer]
                })
                .OrderBy(g => g.Measurement_Record_Date)
                .ThenBy(g => g.Manufacturer)
                .ToList();
 
            const float gramsPerTroyOunce = 31.1035f;
 
            if (unit == "t oz")
            {
                foreach (var item in groupedData)
                {
                    if (item.Pt_Remaining_Gms.HasValue)
                        item.Pt_Remaining_Gms = item.Pt_Remaining_Gms.Value / gramsPerTroyOunce;
 
                    if (item.Ru_Remaining_Gms.HasValue)
                        item.Ru_Remaining_Gms = item.Ru_Remaining_Gms.Value / gramsPerTroyOunce;
                }
            }
 
            ViewBag.fromDate = fromDate;
            ViewBag.toDate = toDate;
            ViewBag.Unit = unit;
 
            return View(groupedData);
        }

    public class MeasurementDataViewModel
    {
        public DateTime Measurement_Record_Date { get; set; }
        public float? Pt_Remaining_Gms { get; set; }
        public float? Ru_Remaining_Gms { get; set; }
        public string Manufacturer { get; set; }
        public string Color { get; set; }
    }
[
    {
        "Measurement_Record_Date": "/Date(1542823200000)/",
        "Pt_Remaining_Gms": 4370,
        "Ru_Remaining_Gms": 5621,
        "Manufacturer": "JX Nippon"
    },
    {
        "Measurement_Record_Date": "/Date(1542823200000)/",
        "Pt_Remaining_Gms": 4571,
        "Ru_Remaining_Gms": 4295,
        "Manufacturer": "Kojundo/Mitsui"
    },
    {
        "Measurement_Record_Date": "/Date(1543168800000)/",
        "Pt_Remaining_Gms": 1785,
        "Ru_Remaining_Gms": 7086,
        "Manufacturer": "JX Nippon"
    },
    {
        "Measurement_Record_Date": "/Date(1543255200000)/",
        "Pt_Remaining_Gms": 36432,
        "Ru_Remaining_Gms": 41800,
        "Manufacturer": "Kurt J. Lesker"
    },
    {
        "Measurement_Record_Date": "/Date(1543428000000)/",
        "Pt_Remaining_Gms": 76360,
        "Ru_Remaining_Gms": 74687,
        "Manufacturer": "Kurt J. Lesker"
    },
    {
        "Measurement_Record_Date": "/Date(1543428000000)/",
        "Pt_Remaining_Gms": 11138,
        "Ru_Remaining_Gms": 9686,
        "Manufacturer": "Materion"
    },
    {
        "Measurement_Record_Date": "/Date(1543428000000)/",
        "Pt_Remaining_Gms": 1329,
        "Ru_Remaining_Gms": 4796,
        "Manufacturer": "Mitsubishi"
    }
]
@using Kendo.Mvc.UI
@using System.Web.Mvc
@using System.Web.Mvc.Html
@using Kendo.Mvc.Extensions
@model IEnumerable<TMS_RND.Controllers.MeasurementDataViewModel>
@using System.Web.Helpers
 
@{
    ViewBag.Title = "Chart";
    Layout = "~/Views/Shared/_Layout.cshtml";
 
    DateTime startDate = ViewBag.fromDate ?? DateTime.Today.AddDays(-6);
    DateTime endDate = ViewBag.toDate ?? DateTime.Today;
    string currentUnit = ViewBag.Unit ?? "gm";
    var manufacturers = Model
        .GroupBy(m => m.Manufacturer)
        .Select(g => new
        {
            Manufacturer = g.Key,
            Color = g.First().Color
        })
        .ToList();
}
 
 
<div class="demo-section wide">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
            From: @(Html.Kendo().DatePicker().Name("fromDate").Value(startDate.ToString("yyyy-MM-dd")))
            To: @(Html.Kendo().DatePicker().Name("toDate").Value(endDate.ToString("yyyy-MM-dd")))
<button id="refreshChart">Refresh Chart</button>
<button id="clearFilter">Clear</button>
<button id="toggleUnit">@(currentUnit == "gm" ? "Switch to Troy oz" : "Switch to gm")</button>
</div>
<div>
<button class="tab" id="totalPoolTab">Total Pool</button>
<button class="tab" id="tmsTab" style="background-color: lightblue;">TMS</button>
</div>
<div>
            @foreach (var manufacturer in manufacturers)
            {
<span style="color:@manufacturer.Color">@manufacturer.Manufacturer</span>
            }
</div>
</div>
<div id="chartContainer">
        @(Html.Kendo().Chart(Model)
            .Name("chart")
            .Title("Historical Pool Data")
            .HtmlAttributes(new { style = "height: 400px;" })
            .Legend(legend => legend.Position(ChartLegendPosition.Bottom))
            .SeriesDefaults(seriesDefaults => seriesDefaults.Line().Stack(false))
            .Series(series => {
                foreach (var manufacturer in manufacturers)
                {
                    var manufacturerData = Model.Where(m => m.Manufacturer == manufacturer.Manufacturer).ToList();
                    series.Line(manufacturerData.Select(m => m.Pt_Remaining_Gms))
                          .Name("Pt - " + manufacturer.Manufacturer)
                          .Color(manufacturer.Color)
                          .Visible(true)
                          .Labels(labels => labels.Visible(true).Format("{0:N2} " + currentUnit));
                    series.Line(manufacturerData.Select(m => m.Ru_Remaining_Gms))
                          .Name("Ru - " + manufacturer.Manufacturer)
                          .Color(manufacturer.Color)
                          .Visible(false)
                          .Labels(labels => labels.Visible(true).Format("{0:N2} " + currentUnit));
                }
            })
            .CategoryAxis(axis => axis.Categories(Model.Select(m => m.Measurement_Record_Date.ToString("dd MMM yyyy")).Distinct()))
            .ValueAxis(axis => axis.Numeric()
                .Line(line => line.Visible(false))
                .Title("Weight (" + currentUnit + ")"))
            .Tooltip(tooltip => tooltip.Visible(true).Format("{0:N2} " + currentUnit))
        )
</div>
</div>
 
<script>
    $(document).ready(function () {
        function toISOStringWithMidday(date) {
            var localDate = new Date(date);
            localDate.setHours(12, 0, 0, 0);
            var offset = localDate.getTimezoneOffset() * 60000;
            var localMidday = new Date(localDate.getTime() - offset);
            return localMidday.toISOString();
        }
 
        $("#refreshChart").click(function () {
            refreshChart();
        });
 
        $("#toggleUnit").click(function () {
            var newUnit = '@currentUnit' == 'gm' ? 't oz' : 'gm';
            refreshChart(newUnit);
        });
 
        $("#clearFilter").click(function () {
            window.location.href = '@Url.Action("ChartTMS", "Target_Measurement_History")';
        });
 
        function refreshChart(newUnit) {
            var selectedFromDate = $("#fromDate").data("kendoDatePicker").value();
            var selectedToDate = $("#toDate").data("kendoDatePicker").value();
            var unitParam = newUnit || '@currentUnit';
 
            if (selectedFromDate && selectedToDate) {
                var difference = Math.abs(selectedToDate.getTime() - selectedFromDate.getTime());
                if (difference > 7 * 24 * 60 * 60 * 1000) {
                    alert("Please select a date range within 7 days.");
                    return;
                }
 
                var fromDateStr = toISOStringWithMidday(selectedFromDate);
                var toDateStr = toISOStringWithMidday(selectedToDate);
 
                window.location.href = '@Url.Action("ChartTMS", "Target_Measurement_History")' + '?fromDate=' + fromDateStr + '&toDate=' + toDateStr + '&unit=' + unitParam;
            } else {
                alert("Please select both from and to dates.");
            }
        }
 
        $("#totalPoolTab").click(function() {
            window.location.href = '@Url.Action("Chart", "Target_Measurement_History")';
        });
 
        $("#tmsTab").click(function() {
            window.location.href = '@Url.Action("ChartTMS", "Target_Measurement_History")';
        });
 
        $("#tmsTab").css("background-color", "lightblue");
 
        $(".tab").click(function() {
            $(".tab").css("background-color", "");
            $(this).css("background-color", "lightblue");
        });
    });
</script>
Georgi
Telerik team
commented on 01 May 2024, 12:45 PM

I believe the issue is because the categories of the values are not adjacent. Could you please test the following and let me know if it works?

            .CategoryAxis(axis => axis.Categories(new DateTime[] { new DateTime(2018, 11, 21), 
                                                                                                                               ...
                                                                                                                new DateTime(2018, 11, 28),
            })) 

No answers yet. Maybe you can help?

Tags
Chart
Asked by
S M Rahiyan
Top achievements
Rank 1
Share this question
or