Dynamic Highcharts In ASP.NET MVC 5

Here, we will learn about creating dynamic Highcharts in ASP.NET MVC 5. We have already seen how we can create the Highcharts with static data, Now its time to create Highcharts with Dynamic data which is used in real-world applications. We will be creating line charts with dynamic data.

Roadmap for Developing the application

  • Creating the ASP.NET application
  • Setting up the Database
  • Inserting Dummy Data for Creating Highcharts
  • Reading data from database
  • Integrating Highcharts Library in the application
  • Creating Line Charts.

Creating the ASP.NET application

Create a new ASP.NET MVC 5 application or use any existing application in which you have to integrate the HighCharts. Install the Entity Framework and EpPlus package from the Nuget using the following command. We will be using excel file for inserting the dummy data.

Install-Package EPPlus
Install-Package EntityFramework

Setting up the Database

We will start by adding the connection string to the Web Config. Add the following connection string in the application.

<connectionStrings>
    <add name="DBConnectionString" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\DynamicHighCharts.mdf;Initial Catalog=DynamicHighCharts;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

Now, we will create the folder for storing the class file for the database. Create two folders. One main folder Entity and inside it add another folder as POCO like this.

Create a Database Context file as CodeHubsContext.cs file in the POCO folder.

public class CodeHubsContext : DbContext
    {
        public CodeHubsContext() : base("DBConnectionString") { }
        public DbSet<Analysis> Analyses { get; set; }
    }

Also, create one file as Analysis.cs file in the same folder.

public class Analysis
    {
        [Key]
        public int Id { get; set; }
        public string Description { get; set; }
        public string Date { get; set; }
        public string Value { get; set; }
    }

Open the Package Manager Console from the Tools options and Type the following command.

Enable-Migrations
Add-Migration Initial
Update-Database

Inserting Dummy Data for Creating Highcharts

We will be using the Excel file for inserting the dummy data for highcharts. You can find the excel file from my GitHub account. I’ll be adding the link at last.

Add the following code in the HomeController

public void AddExcelData()
        {
            try
            {
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                List<Analysis> excelData = new List<Analysis>();
                FileInfo existingFile = new FileInfo($"{AppDomain.CurrentDomain.BaseDirectory}/Content/SampleDBData.xlsx");
                using (ExcelPackage package = new ExcelPackage(existingFile))
                {
                    ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
                    int rowCount = worksheet.Dimension.End.Row;
                    for (int row = 1; row <= rowCount; row++)
                    {
                        try
                        {
                            excelData.Add(new Analysis()
                            {
                                Description = worksheet.Cells[row, 1].Value.ToString().Trim(),
                                Date = worksheet.Cells[row, 2].Value.ToString().Trim(),
                                Value = worksheet.Cells[row, 3].Value.ToString().Trim()
                            });
                        }
                        catch (Exception)
                        {

                        }
                    }
                    _context.Analyses.AddRange(excelData);
                    _context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
            }
        }

Reading data from database

Now, we will actually add the logic for reading the data from the database in proper format. The most important thing here is grouping the data according to our needs. We will be adding group by Description and Date and then sum up the values from the group result. Before that, we will need to apply Order By Date as HighCharts accepts Date in ascending order.

public JsonResult GetHighChartsData()
        {
            try
            {
                if (_context.Analyses.Count() == 0)
                {
                    AddExcelData();
                }
                var highChartsData = _context.Analyses.AsEnumerable().OrderBy(x => Convert.ToDateTime(x.Date)).GroupBy(x => new { x.Description, x.Date }).Select(x => new
                {
                    Title = x.Key.Description,
                    Date = x.Key.Date,
                    Value = x.Sum(y => decimal.Parse(y.Value, CultureInfo.InvariantCulture))
                }).ToList();
                return Json(new { isSuccess = true, data = JsonConvert.SerializeObject(highChartsData) }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { isSuccess = false, message = ex.Message });
            }
        }

Here, we have inserted the data first if there is no data in the database. After that our main Logic is applied as explained above.

Whole code will look like this together

public class HomeController : Controller
    {
        private readonly CodeHubsContext _context = null;
        public HomeController()
        {
            _context = new CodeHubsContext();
        }
        public ActionResult Index() => View();

        public void AddExcelData()
        {
            try
            {
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                List<Analysis> excelData = new List<Analysis>();
                FileInfo existingFile = new FileInfo($"{AppDomain.CurrentDomain.BaseDirectory}/Content/SampleDBData.xlsx");
                using (ExcelPackage package = new ExcelPackage(existingFile))
                {
                    ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
                    int rowCount = worksheet.Dimension.End.Row;
                    for (int row = 1; row <= rowCount; row++)
                    {
                        try
                        {
                            excelData.Add(new Analysis()
                            {
                                Description = worksheet.Cells[row, 1].Value.ToString().Trim(),
                                Date = worksheet.Cells[row, 2].Value.ToString().Trim(),
                                Value = worksheet.Cells[row, 3].Value.ToString().Trim()
                            });
                        }
                        catch (Exception)
                        {

                        }
                    }
                    _context.Analyses.AddRange(excelData);
                    _context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
            }
        }

        public JsonResult GetHighChartsData()
        {
            try
            {
                if (_context.Analyses.Count() == 0)
                {
                    AddExcelData();
                }
                var highChartsData = _context.Analyses.AsEnumerable().OrderBy(x => Convert.ToDateTime(x.Date)).GroupBy(x => new { x.Description, x.Date }).Select(x => new
                {
                    Title = x.Key.Description,
                    Date = x.Key.Date,
                    Value = x.Sum(y => decimal.Parse(y.Value, CultureInfo.InvariantCulture))
                }).ToList();
                return Json(new { isSuccess = true, data = JsonConvert.SerializeObject(highChartsData) }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { isSuccess = false, message = ex.Message });
            }
        }
    }

Integrating Highcharts Library in the application

Open the _Layout.cshtml file from the Shared folder and replace it with the following code.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Dynamic HighCharts</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - Dynamic HighCharts</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script>
    <script src="https://code.highcharts.com/modules/export-data.js"></script>
    <script src="https://code.highcharts.com/modules/accessibility.js"></script>
    @RenderSection("scripts", required: false)
</body>
</html>

Now, its time to write the jQuery code for building the line charts. So open the Index.cshtml file from the Home folder and add the following code in it.

Creating Line Charts

@{
    ViewBag.Title = "Home Page";
}

<div class="row">
    <div class="col-md-12" id="lineCharts">

    </div>
</div>

@section scripts{
    <script>
        var lineSeries = [];
        function groupBy(array, f) {
            var groups = {};
            array.forEach(function (o) {
                var group = JSON.stringify(f(o));
                groups[group] = groups[group] || [];
                groups[group].push(o);
            });
            return Object.keys(groups).map(function (group) {
                return groups[group];
            });
        }
        $(document).ready(function () {
            fetch('/Home/GetHighChartsData').then(res => res.json()).then(res => {
                if (res.isSuccess) {
                    var data = JSON.parse(res.data);
                    var groupedData = groupBy(data, function (item) {
                        return [item.Title]
                    });
                    lineSeries = [];
                    for (var i = 0; i < groupedData.length; i++) {
                        var name = groupedData[i][0]["Title"];
                        var tempLine = [];
                        for (var j = 0; j < groupedData[i].length; j++) {
                            tempLine.push({
                                "x": new Date(groupedData[i][j]["Date"]).valueOf(),
                                "y": parseFloat(groupedData[i][j]["Value"])
                            })
                        }
                        lineSeries.push({
                            "name": name,
                            "data": tempLine
                        });
                    }
                    $('#lineCharts').highcharts({
                        chart: {
                            type: 'line',
                            zoomType: 'x'
                        },
                        title: {
                            text: 'Analysis Range',
                        },
                        xAxis: {
                            type: 'datetime',
                            labels: {
                                format: "{value:%b %e }",
                            }
                        },
                        yAxis: {
                            title: {
                                text: 'Analysis Range Values',
                            },
                        },
                        series: lineSeries
                    });
                }
            });
        });
    </script>
}

Here, we will first group by title for our data and converts the dates into the timestamp format. It will be required for making the data in a format that highcharts accept.

Code in action:

dynamic highcharts

You can find the source code from my Github account from here

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories