【问题标题】:The correct method to populate a Highcharts box plot using JSON使用 JSON 填充 Highcharts 箱线图的正确方法
【发布时间】:2016-03-08 16:27:07
【问题描述】:

虽然我已经通过将静态值写入我的 MVC 5 视图页面来成功创建 Highcharts Box-and-Whisker plot,但现在我正在尝试通过使用控制器中的 JsonResult 函数填充值来做同样的事情。

Highcharts 网站有一个关于custom preprocessing data using JSON 的部分,但到目前为止,我使用该 URL 中显示的方法没有成功,只是将图表类型更改为“boxplot”并定义参数。一个警告框显示从 JsonResult 函数中成功读取了数据值,但出现的图表没有我希望看到的数据。

我检查了 Firebug,在浏览器中查看页面时没有看到 jQuery 错误。

我在这里遗漏了一些明显的东西吗?我在 Visual Studio 中使用 MVC 5 C#。

@section scripts
{
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/highcharts-more.js"></script>
    <script>
        $(function () {

            var options = {
                chart: {
                    renderTo: 'container',
                    type: 'boxplot'                    
                },                
                series: [{}]
            };                       

            $.ajax({
                dataType: "json",
                type: "POST",
                url: "@Url.Action("GetChartData")",                
                cache: false,
                async: false,
                data: { _campus: "@ViewBag.SelectedCampus", 
                       _semester: "@ViewBag.SelectedSemester", 
                       _fy: "FY12" },
                success: function (data) {

                    options.series[0].data = data;
                    var chart = new Highcharts.Chart(options);
                    alert(data); // I see the correct array set in the alert box:
                                 // as written literally:   395,441,457,479,532
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    alert("oops: " + textStatus + ": " + jqXHR.responseText);
                }
            });
        });
    </script>
}

这是它的截图:

如果有什么不同,这里是 JsonResult 函数:

public JsonResult GetChartData(string _campus, string _semester, string _fy)
        {
            IEnumerable<MathAimsScaleScore> query = db.MathAimsScaleScores
                .Where(m => m.Campus == _campus)
                .Where(m => m.Semester == _semester)
                .Where(m=>m.FY==_fy);

            var FyList = query.Select(m => Convert.ToDouble(m.ScaleScore));
            var jsonList = new double[5];

            for (int i = 0; i < 5; i++)
            {
                jsonList[i] = Statistics.FiveNumberSummary(FyList)[i];
            }

            return Json(jsonList.ToArray());
        }

【问题讨论】:

    标签: c# jquery json asp.net-mvc highcharts


    【解决方案1】:

    您正在向图表提供一个 [395,441,457,479,532] 的数据数组,它将解释为 5 个单独的数据点。

    这会导致您发布的内容:

    (所以,如果你将它制作成具有相同数据数组的折线图,你会看到图表试图用你提供的数据做什么:

    但是,因为你不能只画一个点的箱线图,所以什么都没有显示

    .

    你需要提供的是一个数组数组,其中每个点有5个值:

    data: [[395,441,457,479,532]]
    

    这样,内括号包含单个数据点,以及图表绘制箱线图所需的信息:

    小提琴示例:

    【讨论】:

    • “数组数组”最终成为提供解决方案的关键短语。我在自己的答案中发布了我所做的细节——修改后的 JsonResult 和脚本块。
    【解决方案2】:

    我通过重组 JsonResult 和 jQuery 块找到了不同的方法。

    @jlbriggs 很有帮助,因为“Array of Array”评论,然后我可以将其视为罪魁祸首。

    我又经历了几次迭代,使代码越来越简单,重复性越来越低。当前的迭代允许我用一个 ajax 调用填充整个图表。

    // Called from JsonResult (and other functions in the controller).
    public int[] GetFiveNumberSummary(string _campus, string _semester, string _fy)
            {
                IEnumerable<MathAimsScaleScore> query = db.MathAimsScaleScores
                    .Where(m => m.Campus == _campus)
                    .Where(m => m.Semester == _semester)
                    .Where(m => m.FY == _fy);
    
                var FyList = query.Select(m => Convert.ToDouble(m.ScaleScore)).ToList();
    
                var reply = new int[5];
                for (int i = 0; i < 5; i++)
                {
                    reply[i] = Convert.ToInt32(Statistics.FiveNumberSummary(FyList)[i]);
                }
                return reply;       
            }
    
            public JsonResult GetChartData(string _campus, string _semester)
            {           
    
                var FyArray0 =  GetFiveNumberSummary(_campus,_semester,"FY12").ToArray();
                var FyArray1 = GetFiveNumberSummary(_campus, _semester, "FY13").ToArray();
                var FyArray2 = GetFiveNumberSummary(_campus, _semester, "FY14").ToArray();
                var FyArray3 = GetFiveNumberSummary(_campus, _semester, "FY15").ToArray();
    
                int [][] FyArrayBox = new int[4][];
                FyArrayBox[0] = FyArray0;
                FyArrayBox[1] = FyArray1;
                FyArrayBox[2] = FyArray2;
                FyArrayBox[3] = FyArray3;
    
                foreach (var item in FyArrayBox)
                {
                    Debug.WriteLine(item);
                }
    
                return Json(FyArrayBox.ToArray());
            }
    

    我也重组了 jQuery。这与 Highcharts 上的演示的不同之处在于,我在脚本的最开头定义了数组变量和“数组数组”,并在 $.ajax 函数中显式填充它们。

    options 变量指的是预定义的“数组数组”——它在创建图表时具有值。

    @section scripts
    {
        <script src="https://code.highcharts.com/highcharts.js"></script>
        <script src="https://code.highcharts.com/highcharts-more.js"></script>
        <script>
            $(function () {
                // Create empty arrays to hold the data sets
    
                var DataFy12 = [];
                var DataFy13 = [];
                var DataFy14 = [];
                var DataFy15 = [];
                var DataAll = [];
    
                // This is the chart definition that will be called once $.ajax completes
    
                var options = {
                    chart: {
                        renderTo: 'container',
                        type: 'boxplot'
                    },
                    title: { text: 'Box-and-Whisker Plot' },
                    legend: { enabled: false },
                    xAxis: {
                        title: { text: 'School Year' },
                        categories: ['FY12', 'FY13', 'FY14', 'FY15']
                    },
                    yAxis: {
                        title: { text: 'Scale Score' }
                    },
                    series: [{
                        name: "Scale Scores",
                        data: DataAll
                        }]
                };
    
                $.ajax({
                    dataType: "json",
                    type: "POST",
                    url: "@Url.Action("GetChartData")",
                    cache: false, // I want to make sure the most recent data is read
                    async: false, // For some reason this needs to be set false
                    data: {
                        _campus: "@ViewBag.SelectedCampus",
                        _semester: "@ViewBag.SelectedSemester"
                    },
                    success: function (data) {
    
                        // the function calls an "array of arrays",                    
                        // where y is the array at location x
    
                        $.each(data, function (x, y) {                        
                            // divert array elements to correct jQuery array
    
                            switch (x) {
                                case 0:
                                    for (i = 0; i < 5; i++)
                                    {
                                        DataFy12.push(y[i]);
                                    }                                
                                    break;
                                case 1:
                                    for (i = 0; i < 5; i++) {
                                        DataFy13.push(y[i]);
                                    }
                                    break;
                                case 2:
                                    for (i = 0; i < 5; i++) {
                                        DataFy14.push(y[i]);
                                    }
                                    break;
                                case 3:
                                    for (i = 0; i < 5; i++) {
                                        DataFy15.push(y[i]);
                                    }
                                    break;
                                default:
                                    alert('case else');
                            }
                        });       
    
                        // The "DataAll" array is the "array of arrays"
                        // Pushing the each array into DataAll 
                        //    gives Highcharts the data set in a form it understands
    
                        DataAll.push(DataFy12);
                        DataAll.push(DataFy13);
                        DataAll.push(DataFy14);
                        DataAll.push(DataFy15);
    
                        // alert(DataAll) -- Data is verified to be correct
    
                        var chart = new Highcharts.Chart(options);
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        alert("oops: " + textStatus + ": " + jqXHR.responseText);
                    }
                });            
    
            });
        </script>
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      • 2018-01-04
      相关资源
      最近更新 更多