Search code examples
javascriptasp.net-corechartsasp.net-ajax

I can't update my Line Chart Data using AJAX


I want to make an ajax function that will update my line chart, the data in the line chart should be sorted according to the month. There should be a button that submits a value for the selected month to the function for getting the chart's data.

@page
@model Task_CRM.Pages.TrendChartModel
@{
    ViewData["Title"] = "Monthly Line Chart";
}
<div class="card">
    <div class="card-header center">
        <center><strong><h5>Trend Interaksi</h5></strong></center>
    </div>
    <div class="card-body">
        <form method="post">
            <label for="selectMonth">Pilih Bulan:  </label>
            <select id="selectMonth" asp-for="SelectedMonth" asp-items="Model.month"></select>
            <button type="submit" class="btn btn-primary" id="updateChartMonth">Update Chart</button>
        </form>
        <div>
            <canvas id="Trend" width="400" height="200"></canvas>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>

<script>
    $(document).ready(function () {
        $('#monthDropdown').change(function () {
            var selectedMonth = $(this).val();
            $.ajax({
                url:'/TrendChart?handler=GetMonthlyData',
                type:'GET',
                data: { SelectedMonth: selectedMonth },
                success: function(data){
                    var Dates = Data.date;
                    var Dates_Values = Data.Count;

                    var TrendChart = new Chart(document.getElementById('Trend'), {
                        type: 'line',
                        data: {
                            labels: Dates,
                            datasets: [{
                                label: 'Total Interactions',
                                data: Dates_Value,
                                fill: false,
                                borderColor: 'rgba(75, 192, 192, 1)',
                                borderWidth: 2,
                                pointRadius: 5,
                                pointHoverRadius: 8,
                                pointBackgroundColor: 'rgba(75, 192, 192, 1)',
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: false,
                            aspectRatio: 1,
                            title: {
                                display: true,
                                text: 'Total Interactions Over Time'
                            },
                            scales: {
                                x: {
                                    type: 'category',
                                    labels: Dates,
                                    position: 'bottom',
                                    title: {
                                        display: true,
                                        text: 'Tanggal'
                                    }
                                },
                                y: {
                                    beginAtZero: true,
                                    title: {
                                        display: true,
                                        text: 'Total Interactions'
                                    }
                                }
                            }
                        }
                    });
                }error:
                    console.error('Error Fetching Updated Data');
            })
        })
    })
    
</script>

@{
    await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Task_CRM.Data;
using Task_CRM.Models;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;

namespace Task_CRM.Pages
{
    public class TrendChartModel : PageModel
    {
        private readonly Task_CRMContext _context;

        public TrendChartModel(Task_CRMContext context)
        {
            _context = context;
        }

        [BindProperty]
        public List<Interaction> Interaction { get; set; }
        [BindProperty]
        public SelectList month { get; set; }
        public int SelectedMonth { get; set; }


        public void OnGet()
        {
            var currentUser = HttpContext.Session.GetString("Username");

            if (currentUser != null)
            {
                ViewData["Navbar"] = currentUser;
            }

            var uniqueMonth = _context.Interaction.Select(m => m.Tanggal.Month).Distinct().ToList();

            month = new SelectList(uniqueMonth);
        }

        //[HttpGet]
        public IActionResult OnGetGetMonthlyData(int SelectedMonth)
        {

            var Dates = _context.Interaction.Where(d => d.Tanggal.Month == SelectedMonth).Select(d => d.Tanggal).ToList();
            var Count = _context.Interaction.Where(d => d.Tanggal.Month == SelectedMonth).Count();

            var Data = new { Dates, Count };

            return new JsonResult(Data);
        }
    }
}

When i try my code the value of the chart is not showing and


Solution

  • Here are several problems in your code:

    1.Your html code does not contain element which id="monthDropdown", so that the change event cannot be hit. Your select element is: <select id="selectMonth"></select>, so the corresponding js should be:

     $('#selectMonth').change(function () {
    

    2.The parameter in success function is data, so you need use data or data.xxx instead of Data to get the response data.

    3.Your backend response json data is like below:

    {"dates":["2024-02-05T00:00:00","2024-02-15T00:00:00"],"count":2}
    

    the response data is camel case, so you need change your ajax:

    var Dates = data.dates;    
    var Dates_Values = data.count;
    

    4.You misspell the data value in your ajax, it is:

    data: Dates_Values,   //not Dates_Value`
    

    5.The line chart contains x y axis, your x-axis is array of dates and the y-axis is the single count which is not correct, you need modify the following backend code: (Not sure how is your model like and which data you want it be the y axis, you need change it by yourself to make this Count be an array. Note:the linq should GroupBy() one column and then Count())

    var Count = data.Where(d => d.Tanggal.Month == SelectedMonth).Count();
    

    Make it be an array and both of the x and y axis data amount should be the same.Easy to say, if your dates contains two values, your count also needs contain two values. For example the response json data should be like below:

    {"dates":["2024-02-05T00:00:00","2024-02-15T00:00:00"],"count":[2.2,3]}
    

    The whole working code

    @{
        ViewData["Title"] = "Monthly Line Chart";
    }
    <div class="card">
        <div class="card-header center">
            <center><strong><h5>Trend Interaksi</h5></strong></center>
        </div>
        <div class="card-body">
            <form method="post">
                <label for="selectMonth">Pilih Bulan:  </label>
                <select id="selectMonth" asp-for="SelectedMonth" asp-items="Model.month"></select>
                <button type="submit" class="btn btn-primary" id="updateChartMonth">Update Chart</button>
            </form>
            <div>
                <canvas id="Trend" width="400" height="200"></canvas>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    
    <script>
        $(document).ready(function () {
            $('#selectMonth').change(function () {
                var selectedMonth = $(this).val();
                $.ajax({
                    url:'/TrendChart?handler=GetMonthlyData',
                    type:'GET',
                    data: { SelectedMonth: selectedMonth },
                    success: function(data){
                        //the parameter in the function is `data`
                        //you can hard coded it for testing: data={"dates":["2024-02-05T00:00:00","2024-02-15T00:00:00"],"count":[2.2, 3]};
                        var Dates = data.dates;    
                        var Dates_Values = data.count;    //the response json data is camel case
    
                        var TrendChart = new Chart(document.getElementById('Trend'), {
                            type: 'line',
                            data: {
                                labels: Dates,
                                datasets: [{
                                    label: 'Total Interactions',
                                    data: Dates_Values,     //it should be `Dates_Values`
                                    fill: false,
                                    borderColor: 'rgba(75, 192, 192, 1)',
                                    borderWidth: 2,
                                    pointRadius: 5,
                                    pointHoverRadius: 8,
                                    pointBackgroundColor: 'rgba(75, 192, 192, 1)',
                                }]
                            },
                            options: {
                                responsive: true,
                                maintainAspectRatio: false,
                                aspectRatio: 1,
                                title: {
                                    display: true,
                                    text: 'Total Interactions Over Time'
                                },
                                scales: {
                                    x: {
                                        type: 'category',
                                        labels: Dates,
                                        position: 'bottom',
                                        title: {
                                            display: true,
                                            text: 'Tanggal'
                                        }
                                    },
                                    y: {
                                        beginAtZero: true,
                                        title: {
                                            display: true,
                                            text: 'Total Interactions'
                                        }
                                    }
                                }
                            }
                        });
                    },
                    error: function () {
                        console.error('Error Fetching Updated Data');
                    }
    
                        
                })
            })
        })
        
    </script>
    
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
    

    Backend:

    public IActionResult OnGetGetMonthlyData(int SelectedMonth)
    {
        //hard coded for easy testing
        var Dates = new[] { "2024-02-05T00:00:00", "2024-02-15T00:00:00" };
        var Count = new[] { 2.2,3};
    
        var Data = new { Dates, Count };
    
        return new JsonResult(Data);
    }
    

    Result: enter image description here