首页 > 解决方案 > Chart.JS 获取图表的 Json 数据并返回类型等于特定类型的数据集

问题描述

我正在处理我网站仪表板中的图表。折线图将有 3 组可能更多的线。我有 json 数据回来了,我相信我需要它。问题是如何分离每个数据集中的数据。下面是我的 json 代码。

    [HttpGet]
    public ActionResult GetChartData()
    {
        AccountingEntities acct = new AccountingEntities();

        var q = from t in acct.TestTransactions
                 group t by new
                 {
                     t.TransactionDate.Year,
                     t.TransactionDate.Month,
                     type = t.Type
                 } into g
                 select new
                 {
                     Types = g.Key.type,
                     Total = g.Sum(t => t.DebitAmount)
                 };

        return Json(new { result = q }, JsonRequestBehavior.AllowGet);
    }

这是我的 JavaScript 代码。现在它确实返回一组,当我添加下一部分数据时,它会在我拥有的数据之上增加额外的月份。我的数据是一月到三月的,当我为“服务”添加一月到三月时,我现在在一行中得到一月到六月的数据。我想按类型分离数据集 - 零件销售、服务和设备..

     function SalesByMonth() {

        $.ajax({
            url: '@Url.Action("GetChartData", "Dashboard")',
            data: JSON,
            contentType: "application/json; charset=utf-8",
            method: "get",
            dataType: "json",
            error: function (_, err) {
                console.log(_, err)
            },
            success: function (response) {

                console.log(response);
                var jsonresult = response
                console.log(data)

                var labels = jsonresult.result.map(function (e) {
                    return e.Types;
                });
                var data = jsonresult.result.map(function (e) {
                    return e.Total;
                });

                var ctx = document.getElementById("monthlySalesChart").getContext("2d");
                var cpieChart = new Chart(ctx, {
                    type: 'line',
                    data: {
                        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
                        datasets: [{

                            label: 'Parts Sales',
                            backgroundColor: 'rgb(210, 214, 222)',
                            fill: false,
                            //strokeColor: 'rgb(210, 214, 222)',
                            //pointColor: 'rgb(210, 214, 222)',
                            //pointStrokeColor: '#c1c7d1',
                            //pointHighlightFill: '#fff',
                            //pointHighlightStroke: 'rgb(220,220,220)',
                            data: data,
                            borderWidth: 1
                        },
                        {
                            label: 'Service Sales',
                            backgroundColor: 'rgb(210, 214, 250)',
                            fill: false,
                            //strokeColor: 'rgb(210, 214, 222)',
                            //pointColor: 'rgb(210, 214, 222)',
                            //pointStrokeColor: '#c1c7d1',
                            //pointHighlightFill: '#fff',
                            //pointHighlightStroke: 'rgb(220,220,220)',
                            data: [4500, 10000, 8000, 11000, 13000, 14500, 22000],
                            borderWidth: 1
                            

                        },
                        {
                            label: 'Machine Sales',
                            backgroundColor: 'rgba(60,141,188,0.9)',
                            fill: false,
                            //strokeColor: 'rgba(60,141,188,0.8)',
                            //pointColor: '#3b8bba',
                            //pointStrokeColor: 'rgba(60,141,188,1)',
                            //pointHighlightFill: '#fff',
                            //pointHighlightStroke: 'rgba(60,141,188,1)',
                            data: [10000, 22000, 50000, 32000, 56000, 87000, 90000],
                            borderWidth: 1

                        }],

                    },
                    options: {
                        scales: {

                            xAxes: [{
                                gridLines: {
                                    display: false
                                }
                            }],
                            yAxes: [{
                                //gridLines: {
                                //    display: false
                                //},
                                ticks: {
                                    beginAtZero: false,
                                    min: 200,
                                    max: 200000,
                                    stepsize: 1000,
                                    callback: function (value, index, values) {

                                        value = value.toString();
                                        value = value.split(/(?=(?:...)*$)/);
                                        value = value.join(',');
                                        return '$' + value + '.00';
                                    }

                                }
                            }]
                        }
                    }
                });

            }
        });
    };

谢谢你的帮助!

更新 - 添加了 Json 结果

{result: Array(6)}
    result: Array(6)
    0: {Types: "Parts Order", Total: 5100}
    1: {Types: "Parts Order", Total: 4230}
    2: {Types: "Parts Order", Total: 5990}
    3: {Types: "Service", Total: 13530}
    4: {Types: "Service", Total: 14380}
    5: {Types: "Service", Total: 15390}
    length: 6
    __proto__: Array(0)
    __proto__: Object

如果可能的话,还希望图表显示当前年份..

标签: javascriptc#asp.net-mvcchart.js

解决方案


我了解您正在寻找一种方法将JSON结果转换datasets为可以由Chart.js.

jsonresult您可以首先从使用中提取唯一标签Array.reduce()

const labels = jsonresult.result.reduce((acc, o) => acc.includes(o.Types) ? acc : acc.concat(o.Types), []);

然后您可以创建datasets如下所示的。请注意,bgColorsborderColors是需要包含至少与预期数据集数量一样多的颜色定义的数组。

const datasets = labels.map((l, i) => ({
  label: l,
  data: jsonresult.result.filter(o => o.Types == l).map(o => o.Total),
  fill: false,
  backgroundColor: bgColors[i],  
  borderColor: borderColors[i],
  ...
}));

请查看您修改后的代码,看看它是如何工作的。

const jsonresult = {
  result: [
    {Types: "Parts Order", Total: 5100},
    {Types: "Parts Order", Total: 4230},
    {Types: "Parts Order", Total: 5990},
    {Types: "Service", Total: 13530},
    {Types: "Service", Total: 14380},
    {Types: "Service", Total: 15390}
  ]
};

const labels = jsonresult.result.reduce((acc, o) => acc.includes(o.Types) ? acc : acc.concat(o.Types), []);
const datasets = labels.map((l, i) => ({
  label: l,
  data: jsonresult.result.filter(o => o.Types == l).map(o => o.Total),
  fill: false,
  backgroundColor: ['rgba(210, 214, 222, 0.6)', 'rgba(60,141,188, 0.6)'][i],  
  borderColor: ['rgb(210, 214, 222)', 'rgb(60,141,188)'][i],
  pointHoverBackgroundColor: '#fff',
  pointHoverBorderColor: ['rgb(220,220,220)', 'rgb(60,141,188)'][i], 
  borderWidth: 1
}));

new Chart('monthlySalesChart', {
  type: 'line',
  data: {
    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    datasets: datasets,
  },
  options: {
    scales: {
      xAxes: [{
        gridLines: {
          display: false
        }
      }],
      yAxes: [{
        ticks: {
          min: 200,
          max: 100000,
          stepSize: 20000,
          callback: v => '$' + v.toString().split(/(?=(?:...)*$)/).join(',') + '.00'
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
<canvas id="monthlySalesChart" height="80"></canvas>


推荐阅读