简体   繁体   中英

How to build ajax-chartjs line-chart in asp mvc application?

I have following code in my view:

@Styles.Render("~/Content/newcss")
@Scripts.Render("~/bundles/chartscripts")
@Scripts.Render("~/scripts/jquery-1.10.2.js")
@Scripts.Render("~/scripts/jquery.unobtrusive-ajax.js")
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.bundle.min.js">
</script>

<script>
$.ajax({
    type: "post",
    url: "/GraphicsController/AjaxChart",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function () {
    var ctx1 = document.getElementById("Linecanvas").getContext("2d");
    window.myBar = new Chart(ctx1,
        {   type: 'line',
            data: {
                labels: [@Html.Raw(Json.Encode(@ViewBag.ContentIds))],
                datasets: [{
                        label: "Common Responses",
                        backgroundColor: "rgba(75,192,192,0.4)",
                        borderWidth: 2,
                        data: [@Html.Raw(Json.Encode(@ViewBag.ContentIds))]
                    },{
                        label: "Delayed Responses",
                        backgroundColor: "rgba(75,192,192,0.4)",
                        borderWidth: 2,
                        data: 
[@Html.Raw(Json.Encode(@ViewBag.DelayedResponseTimes))]
                    }]},
            options:{title:
                    {display: true,
                        text: "Graphic"},
                    responsive: true,
                    maintainAspectRatio: true
                }});},
    error: function OnErrorCall_(repo) {alert("Woops something went wrong, 
pls try later !");}});
</script>  
</head>
<body>
<div id="wrapper">
    <div id="div-chart">
        <canvas id="Linecanvas"></canvas>
    </div>
    ...
<body>

And in controller:

[HttpPost]
public ActionResult AjaxChart() {
  IEnumerable < DBContent > contents = db.DBContents;

  var delayedResponses = contents.Where(r => r.DelayedResponseTime != 0).Select(x => x.DelayedResponseTime);
  var commonResponses = contents.Where(r => r.CommonResponseTime != 0).Select(x => x.CommonResponseTime);
  ViewBag.DelayedResponseTimes = delayedResponses.ToList();
  ViewBag.CommonResponseTimes = commonResponses.ToList();

  var ContentIds = new List < int > () {};
  for (var i = 1; i <= delayedResponses.Count(); i++) {
    ContentIds.Add(i);
  }
  ViewBag.ContentIds = ContentIds;
  return Json(delayedResponses.ToList(), JsonRequestBehavior.AllowGet);
}

I tried to build line chart with chartjs, and without Ajax I have done it, but I want to my chart rebuild automatically without page refreshing and without any actions on page (triggers for Ajax like clicking buttons etc) when I get a new items in the database. With this code I always go to the error block.

Thanks ... it Successfully works for me. But there is little change needed:

public ActionResult AjaxChart()

to:

public JsonResult AjaxChart()

You cannot use ViewBag with Ajax, you can only return one single result object. Combine all those returned objects as properties of one parent object:

[HttpGet]
public ActionResult AjaxChart() {
    IEnumerable<DBContent> contents = db.DBContents;

    var delayedResponses = contents.Where(r => r.DelayedResponseTime != 0)
                                   .Select(x => x.DelayedResponseTime);
    var commonResponses = contents.Where(r => r.CommonResponseTime != 0)
                                  .Select(x => x.CommonResponseTime);

    var ContentIds = new List<int>();
    for (var i = 1; i <= delayedResponses.Count(); i++) {
        ContentIds.Add(i);
    }

    var result = new {
        DelayedResponseTimes = delayedResponses.ToList(),
        CommonResponseTimes = commonResponses.ToList(),
        ContentIds = ContentIds
    };
    return Json(result, JsonRequestBehavior.AllowGet);
}

Now, in your jQuery, you need to get the data (you're not doing that). Change the line:

success: function () {

to:

success: function (result) {

And then you need to change all those line using ViewBag to using the result parameter:

success: function(result) {
  var ctx1 = document.getElementById("Linecanvas").getContext("2d");
  window.myBar = new Chart(ctx1, {
    type: 'line',
    data: {
      labels: result.ContentIds,
      datasets: [{
        label: "Common Responses",
        backgroundColor: "rgba(75,192,192,0.4)",
        borderWidth: 2,
        data: result.CommonResponseTimes
      }, {
        label: "Delayed Responses",
        backgroundColor: "rgba(75,192,192,0.4)",
        borderWidth: 2,
        data: result.DelayedResponseTimes
      }]
    },
    options: {
      title: {
        display: true,
        text: "Graphic"
      },
      responsive: true,
      maintainAspectRatio: true
    }
  });
},

And finally, in the URL to your method, you must use the name of the controller without the suffix, so change this line:

url: "/GraphicsController/AjaxChart",

to:

url: "/Graphics/AjaxChart",

It is better to let ASP generate the URL for you, in case you change your routing or rename your method:

url: @Url.Action(nameof(GraphicsController.AjaxChart), "Graphics"),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM