Home > OS >  Is there a way to pass Dynamic JSON data queried from a database to display in chart format (Google
Is there a way to pass Dynamic JSON data queried from a database to display in chart format (Google

Time:12-28

I have an ASP.NET Core 3.1 Web App that has functionality where a user can input a stock ticker and a chart is created for them using a query to retrieve data (Price & Date) for that ticker. I've followed basic Google Chart API walkthroughs to implement in my app. It works if the data is hardcoded in the JSON method, but if I want to dynamically view a chart based on whatever ticker I enter, the chart doesn't receive the JSON data needed.

What I tried was having a Ticker Entry page (Action method) with a Form that returns the user inputted ticker to the Chart action method. What I wanted was for the Chart method to handle all the LINQ Querying and transforming the list into a JSONList, so that it can be passed into it's View method. I'll post the code in order.

TickerEntry.cshtml

@using (Html.BeginForm("Chart", "Stocks", FormMethod.Get))
{
    <table>
        <tr>
            <td>Enter a Ticker to pull up its chart: </td>
            <td>@Html.TextBox("stockTicker")</td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Submit"></td>
        </tr>
    </table>
}

StocksController.cs

public List<StockLineChart> GetStockData(string stockTicker)
        {
            var list = new List<StockLineChart>();
            var result = (from s in _context.HistoricalDatas
                          where s.Ticker == stockTicker
                          select new { s.Price, s.DateOfClose });
            list = result.AsEnumerable()
                              .Select(sl => new StockLineChart
                              {
                                  Price = sl.Price,
                                  DateOfClose = Convert.ToDateTime(sl.DateOfClose)
                              }).ToList();

            return list;

           
        }

        public IActionResult TickerEntry()
        {            
            return View();
        }


 public IActionResult Chart(string stockTicker)
        {     
             //Returns the Chart View, but passes in the list of stock price&date transformed into JSON
            return View(GetLineChartJSON(GetStockData(stockTicker))); 
        }



public JsonResult GetLineChartJSON(List<StockLineChart> stockList)
        {   
            
            return Json(new { JSONList = stockList });
        }


Chart.cshtml

@{
    ViewData["Title"] = "Chart";
}

<div >
    <div >
        <div id="chartdiv" style="width:1000px;height:350px;">
        </div>
    </div>
</div>

@section Scripts
{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">

        // Load the Visualization API and the corechart package.
        google.charts.load('current', { 'packages': ['corechart'] });

        // Set a callback to run when the Google Visualization API is loaded.
        google.charts.setOnLoadCallback(DrawChart);


        // Callback that creates and populates a data table,
        // instantiates the pie chart, passes in the data and
        // draws it.
        function DrawChart() {
            $(function () {
                $.ajax({
                    type: 'GET',
                    url: '/Stocks/GetLineChartJSON',
                    success: function (chartsdata) {
                        // Callback that creates and populates a data table,
                        // instantiates the pie chart, passes in the data and
                        // draws it.

                        //get jsonList from Object
                        var Data = chartsdata.jsonList;
                        var data = new google.visualization.DataTable();

                        
                        data.addColumn('string', 'DateOfClose');
                        data.addColumn('number', 'Price');

                        //Loop through each list data
                        for (var i = 0; i < Data.length; i  ) {
                            data.addRow([Data[i].dateOfClose, Data[i].price]);
                        }

                        // Instantiate and draw our chart, passing in some options
                        var chart = new google.visualization.LineChart(document.getElementById('chartdiv'));

                        //Draw line chart command with data and chart options
                        chart.draw(data,
                            {
                                title: "Stock Chart",
                                position: "top",
                                fontsize: "14px",
                            });

                    },
                    error: function () {
                        alert("Error loading data! Please try again.");
                    }
                });
            })

        }
    </script>
}

What I believe is that the GetLineChartJSON shouldn't take any parameters, but it's hard to do this because it needs some type of data(Either a ticker to query the list, or the list itself so it can transform into JSON)

For example, this would work:

StockController.cs

public JsonResult GetLineChartJSON()
        {

            var list = new List<StockLineChart>();
            var result = (from s in _context.HistoricalDatas
                          where s.Ticker == "AC"
                          select new { s.Price, s.DateOfClose });
            list = result.AsEnumerable()
                              .Select(sl => new StockLineChart
                              {
                                  Price = sl.Price,
                                  DateOfClose = Convert.ToDateTime(sl.DateOfClose)
                              }).ToList();

       

            return Json(new { JSONList = list });
        }

Note that there's nothing passed into this method, and stockTicker has now been hardcoded in as "AC", which I don't want, because the user chooses what stock they want to see.

I hope I'm not confusing with the explanation of my problem, I'm willing to clarify any misunderstanding.

CodePudding user response:

A whole working demo here you could follow:

Chart.cshtml

@{
    ViewData["Title"] = "Chart";
}
<div >
    <div >
        <div id="chartdiv" style="width:1000px;height:350px;">
        </div>
    </div>
</div>

@section Scripts
    {
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">

            google.charts.load('current', { 'packages': ['corechart'] });
            google.charts.setOnLoadCallback(DrawChart);

            function DrawChart() {
                $(function () {

                    var Data = @Html.Raw(ViewBag.StockTicker);  //get the ViewBag object

                    var data = new google.visualization.DataTable();
                    data.addColumn('string', 'DateOfClose');
                    data.addColumn('number', 'Price');

                    for (var i = 0; i < Data.length; i  ) {
                        //change uppercase here....
                        data.addRow([Data[i].DateOfClose, Data[i].Price]); 
                    }

                    var chart = new google.visualization.LineChart(document.getElementById('chartdiv'));
                    chart.draw(data,
                    {
                        title: "Stock Chart",
                        position: "top",
                        fontsize: "14px",
                    });
                })
            }               
    </script>
}

Controller

public IActionResult TickerEntry()
{
    return View();
}
public List<StockLineChart> GetStockData(string stockTicker)
{
    var list = new List<StockLineChart>();
    var result = (from s in _context.HistoricalDatas
                    where s.Ticker == stockTicker
                    select new { s.Price, s.DateOfClose });
    list = result.AsEnumerable()
                        .Select(sl => new StockLineChart
                        {
                            Price = sl.Price,
                            DateOfClose = Convert.ToDateTime(sl.DateOfClose)
                        }).ToList();

    return list;
}

public IActionResult Chart(string stockTicker)
{
    //Use ViewBag instead....
    ViewBag.StockTicker =JsonConvert.SerializeObject(GetStockData(stockTicker));   
    return View();
}

//no need GetLineChartJSON method any more....
  • Related