Generating Chart Dynamically In MVC Using Chart.js

Introduction

In this article, we shall learn how to generate charts like Bar charts, Line charts, and Pie charts in an MVC web application dynamically using Chart.js which is an important JavaScript library for generating charts. Chart.js is a simple and flexible charting option that provides easy implementation to web developers and designers. We can generate almost every type of chart using chart.js. We shall implement it step by step for generating the chart, as shown below.

Let's get started now.

Create MVC Web Application

To create an MVC web application, first, open Visual Studio and click on File >> New project, as shown in the below image.

New project

It will open a new window as shown below. Here, you have to click on the web option. Now, give the name of the project and set the location of the project where you want to save the file.

Location

Now, to select the project template, you have to click on the MVC template and I have used "No Authentication" as highlighted below.

 MVC template

Now, the application has already been created and all the files as per the MVC web template are also created in the application. It looks like below.

MVC web template

Adding Controller to the Application

To add a controller, right-click on the Controllers folder available in the Solution Explorer and select the "Add Controller" option.

Add >> Controller.

Add Controller

The new next window will open where choose the option: MVC 5 Controller - Empty and click on the "Add" button, as shown below.

MVC 5 Controller

Now finally, you have to give the name of the Controller and click on the "Add" button. I have given the name of the controller as ChartInMVCRuntimeController. Here, you do not have to remove the word Controller from the controller name as it is the default.

ChartInMVCRuntimeController

Now, the Controller has been added and we can see it in the Controllers folder available in Solution Explorer.

Controllers folder

Adding View to the Application

First, right-click on the Views folder and select the "Add New Folder" option as shown below. Here, give the name of the folder as RuntimeChart as I have given in my project.

Add New Folder

Now, right-click on the newly created folder RuntimeChart and select the "Add View" option, as shown below.

Add View

Now, give the name of the View as below.

View

Now, the new View has been added which can be shown in Solution Explorer, as shown below.

Solution Explorer

Calling Action To Return View

Now, modify the Index action as shown below to return the view which will display on the browser.

public ActionResult Index()
{
    return View("~/Views/RuntimeChart/ChartInMVC.cshtml");
}

Adding Table and TextBox to View

To add a simple HTML table and a textbox for entering the value, just copy the below HTML code and paste it to the new View that you have just added.

The below HTML code also contains three separate divs which have been used to generate the chart dynamically later.

@{
    ViewBag.Title = "ChartInMVC";
}

<style type="text/css">
    label {
        font-weight: normal;
        font-size: 11px;
        vertical-align: middle;
    }

    body {
        color: black;
    }

    textbox {
        font-weight: normal;
        font-size: 11px;
        vertical-align: middle;
        color: black;
    }

    .form-control, select {
        font-weight: normal;
        font-size: 11px;
    }

    .container {
        width: 80%;
        margin: 15px auto;
        color: black;
    }
</style>

@using (Html.BeginForm("", "", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div class="form-horizontal">
        <div class="row">
            <div class="col-md-12">
                <div class="form-horizontal">
                    <div class="row">
                        <div class="col-md-12">
                            <div class="col-md-4">
                                <div class="form-group">
                                    <div class="col-md-8">
                                        <label class="control-label">Enter Your Expenses Below</label>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-md-12">
                            <div class="col-md-12">
                                <div class="form-group">
                                    <div class="col-md-12">
                                        <table class="table table-bordered table-responsive">
                                            <thead>
                                                <tr>
                                                    <th scope="col">
                                                        <label class="control-label">Education</label>
                                                    </th>
                                                    <th scope="col">
                                                        <label class="control-label">Lodging</label>
                                                    </th>
                                                    <th scope="col">
                                                        <label class="control-label">Fooding</label>
                                                    </th>
                                                    <th scope="col">
                                                        <label class="control-label">Travelling</label>
                                                    </th>
                                                    <th scope="col">
                                                        <label class="control-label">Communication</label>
                                                    </th>
                                                    <th scope="col">
                                                        <label class="control-label">Others</label>
                                                    </th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <tr>
                                                    <th scope="row">
                                                        <input type="text" class="form-control" id="txtEducation" />
                                                    </th>
                                                    <th scope="row">
                                                        <input type="text" class="form-control" id="txtLodging" />
                                                    </th>
                                                    <th scope="row">
                                                        <input type="text" class="form-control" id="txtFooding" />
                                                    </th>
                                                    <th scope="row">
                                                        <input type="text" class="form-control" id="txtTravelling" />
                                                    </th>
                                                    <th scope="row">
                                                        <input type="text" class="form-control" id="txtCommunication" />
                                                    </th>
                                                    <th scope="row">
                                                        <input type="text" class="form-control" id="txtOthers" />
                                                    </th>
                                                </tr>
                                                <tr>
                                                    <th scope="row" colspan="2">
                                                        <div id="chartContainerPie" class="containerPie">
                                                            <canvas id="myChart"></canvas>
                                                        </div>
                                                    </th>
                                                    <th scope="row" colspan="2">
                                                        <div id="chartContainer" class="container">
                                                            <canvas id="myChartPie"></canvas>
                                                        </div>
                                                    </th>
                                                    <th scope="row" colspan="2">
                                                        <div id="chartContainerLine" class="containerLine">
                                                            <canvas id="myChartLine"></canvas>
                                                        </div>
                                                    </th>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
}

Now run the application and it will look like as below in the browser.

Run Application

Adding Jquery Reference To View

Now, to add a jQuery reference to your View, just add the below code in the View.

<script src="~/Scripts/jquery-1.10.2.js"></script>

Adding Chart.js Reference To View

To add the chart.js reference to the application, go to the site here and select the version of the chart.js from the dropdown as shown below. Now, include the link in your application in the script tag, as shown below.

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.js"></script>

Chart.js Reference

Adding Action To Controller

Now we need to add another action for getting the result into JSON format which we will assign to the chart datasource. Here, we will return the result into a JSON string containing.

[HttpPost]
public JsonResult NewChart(
    string strEducation, 
    string strLodging, 
    string strFooding, 
    string strTravelling, 
    string strCommunication, 
    string strOthers,
    decimal educationValue, 
    decimal lodgingValue, 
    decimal foodingValue, 
    decimal travellingValue, 
    decimal communicationValue, 
    decimal othersValue)
{
    educationValue = Math.Round(educationValue, 0);
    lodgingValue = Math.Round(lodgingValue, 0);
    foodingValue = Math.Round(foodingValue, 0);
    travellingValue = Math.Round(travellingValue, 0);
    communicationValue = Math.Round(communicationValue, 0);

    List<object> iData = new List<object>();
    
    // Creating sample data
    DataTable dt = new DataTable();
    dt.Columns.Add("Expense", System.Type.GetType("System.String"));
    dt.Columns.Add("ExpenseValues", System.Type.GetType("System.Int32"));

    // For Education
    DataRow dr = dt.NewRow();
    dr["Expense"] = strEducation;
    dr["ExpenseValues"] = educationValue;
    dt.Rows.Add(dr);

    // For Lodging
    dr = dt.NewRow();
    dr["Expense"] = strLodging;
    dr["ExpenseValues"] = lodgingValue;
    dt.Rows.Add(dr);

    // For Fooding
    dr = dt.NewRow();
    dr["Expense"] = strFooding;
    dr["ExpenseValues"] = foodingValue;
    dt.Rows.Add(dr);

    // For Travelling
    dr = dt.NewRow();
    dr["Expense"] = strTravelling;
    dr["ExpenseValues"] = travellingValue;
    dt.Rows.Add(dr);

    // For Communication
    dr = dt.NewRow();
    dr["Expense"] = strCommunication;
    dr["ExpenseValues"] = communicationValue;
    dt.Rows.Add(dr);

    // For Others
    dr = dt.NewRow();
    dr["Expense"] = strOthers;
    dr["ExpenseValues"] = othersValue;
    dt.Rows.Add(dr);

    // Looping and extracting each DataColumn to List<Object>
    foreach (DataColumn dc in dt.Columns)
    {
        List<object> x = new List<object>();
        x = (from DataRow drr in dt.Rows select drr[dc.ColumnName]).ToList();
        iData.Add(x);
    }
    
    ViewBag.ChartData = iData;

    // Source data returned as JSON
    return Json(iData, JsonRequestBehavior.AllowGet);
}

Adding Function For Passing Data In Action And Generating Chart

Now, we need to add the below jQuery function which will pass data to the action and get the JSON value that we have assigned as a data source to the chart.

<script type="text/javascript">
    function GenerateRuntimeGraph() {
        var educationValue = $('#txtEducation').val();
        var lodgingValue = $('#txtLodging').val();
        var foodingValue = $('#txtFooding').val();
        var travellingValue = $('#txtTravelling').val();
        var communicationValue = $('#txtCommunication').val();
        var othersValue = $('#txtOthers').val();

        // Setting default values
        if (educationValue == "") {
            educationValue = 0;
        }
        if (lodgingValue == "") {
            lodgingValue = 0;
        }
        if (foodingValue == "") {
            foodingValue = 0;
        }
        if (travellingValue == "") {
            travellingValue = 0;
        }
        if (communicationValue == "") {
            communicationValue = 0;
        }
        if (othersValue == "") {
            othersValue = 0;
        }

        $.ajax({
            type: "POST",
            url: '@Url.Action("NewChart", "ChartInMVCRuntime")',
            data: JSON.stringify({
                "strEducation": "Education",
                "strLodging": "Lodging",
                "strFooding": "Fooding",
                "strTravelling": "Travelling",
                "strCommunication": "Communication",
                "strOthers": "Others",
                educationValue: educationValue,
                lodgingValue: lodgingValue,
                foodingValue: foodingValue,
                travellingValue: travellingValue,
                communicationValue: communicationValue,
                othersValue: othersValue
            }),
            contentType: "application/json",
            dataType: "json",
            success: function (chData) {
                var aData = chData;
                var aLabels = aData[0];
                var aDatasets1 = aData[1];

                // For Bar Chart
                var ctx = document.getElementById("myChart").getContext('2d');
                ctx.height = 900;
                var myChart = new Chart(ctx, {
                    type: 'bar',
                    height: "230px",
                    width: "300px",
                    autoSkip: false,
                    responsive: false,
                    animation: false,
                    showDatapoints: true,
                    legend: { position: 'bottom' },
                    data: {
                        labels: ["Education", "Lodging", "Fooding", "Travelling", "Communication", "Others"],
                        datasets: [{
                            label: 'Monthly Expenses',
                            data: [educationValue, lodgingValue, foodingValue, travellingValue, communicationValue, othersValue],
                            backgroundColor: ["red", "blue", "green", "yellow", "pink", "brown"]
                        }]
                    },
                    options: {
                        events: ['click'],
                        scaleShowValues: true,
                        scales: {
                            yAxes: [{
                                ticks: {
                                    beginAtZero: true
                                }
                            }],
                            xAxes: [{
                                ticks: {
                                    autoSkip: false
                                }
                            }]
                        }
                    }
                });

                // For Pie Chart
                var ctx1 = document.getElementById("myChartPie").getContext('2d');
                var myChart = new Chart(ctx1, {
                    type: 'pie',
                    height: "230px",
                    width: "300px",
                    responsive: false,
                    animation: false,
                    legend: { position: 'bottom' },
                    data: {
                        labels: ["Education", "Lodging", "Fooding", "Travelling", "Communication", "Others"],
                        datasets: [{
                            label: 'Monthly Expenses',
                            data: [educationValue, lodgingValue, foodingValue, travellingValue, communicationValue, othersValue],
                            backgroundColor: ["red", "blue", "green", "yellow", "pink", "brown"]
                        }]
                    },
                    options: {
                        events: ['click']
                    }
                });

                // For Line Chart
                var ctx = document.getElementById("myChartLine").getContext('2d');
                var myChart = new Chart(ctx, {
                    type: 'line',
                    height: "230px",
                    width: "300px",
                    responsive: false,
                    animation: false,
                    legend: { position: 'bottom' },
                    data: {
                        labels: ["Education", "Lodging", "Fooding", "Travelling", "Communication", "Others"],
                        datasets: [{
                            label: 'Monthly Expenses',
                            data: [educationValue, lodgingValue, foodingValue, travellingValue, communicationValue, othersValue],
                            backgroundColor: "rgb(66, 134, 244)"
                        }]
                    },
                    options: {
                        events: ['click'],
                        scaleShowValues: true,
                        scales: {
                            yAxes: [{
                                ticks: {
                                    beginAtZero: true
                                }
                            }],
                            xAxes: [{
                                ticks: {
                                    autoSkip: false
                                }
                            }]
                        }
                    }
                });

            },
            "error": function (data) {
                alert("Some Error Occurred!");
            }
        });
    }
</script>

Adding Textbox Event

Now to add calling the action and passing textbox value to action we need to add the below events in jQuery into the view. All the events are on the key press event of the textbox.

// Calling Above Function On Key Press Event
$("#txtEducation").keyup(function() {
    GenerateRuntimeGraph();
});

$("#txtLodging").keyup(function() {
    GenerateRuntimeGraph();
});

$("#txtFooding").keyup(function() {
    GenerateRuntimeGraph();
});

$("#txtTravelling").keyup(function() {
    GenerateRuntimeGraph();
});

$("#txtCommunication").keyup(function() {
    GenerateRuntimeGraph();
});

$("#txtOthers").keyup(function() {
    GenerateRuntimeGraph();
});

Run The Application

Now we have almost completed the steps needed. So, run the application and it will show in the browser as shown below. Here you need to enter the value of expenses and the chart will be generated instantly as shown below.

Application

Summary

In this article, we have seen how to create an MVC web application and learned to generate a chart in MVC dynamically using chart.js and jQuery. Apart from this, we have seen how to write a jQuery function and learned how to call a jQuery function on the keypress event of the textbox.

I hope you learned and enjoyed it. I look forward to seeing your feedback.


Similar Articles