【问题标题】:Draw pie chart using spring boot, thymeleaf, js, highchart but can't使用spring boot、thymeleaf、js、highchart绘制饼图但不能
【发布时间】:2021-12-09 15:33:27
【问题描述】:

我是 js 和 spring 的新手,现在我想创建一个 html 仪表板,这个页面将有一个带有饼图的小 div。但我无法创建饼图。 我在 youtube 上尝试了一些教程,但现在我想将值传递给 ajax 或类似的东西来获取饼图。 这是我的代码: admin_homepage.html:

<div class="col-xl-4 col-lg-5">
                    <div class="card shadow mb-4">
                        <!-- Thay chart vào thẻ div này -->
                        <div class="card-body">
                            <div class="chart-pie pt-4 pb-2">
                                <div id="chartContainer" style="height: 370px; width: 100%;"></div> 
                            </div>
                        </div>
                    </div>
                </div>

<script type="text/javascript">
    $.ajax({
        /* for pie chart */
        url: "admin_home",

        success: function(result){
            /* pie chart starts here */
            var series = [];
            var data = [];

            for(var i = 0; i < result.length; i++){
                var object = {};
                object.name = result[i].catName.toUpperCase();
                object.y = result[i].catCount;
                data.push(object);
            }
            var seriesObject = {
                name: 'Course By Category',
                colorByPoint: true,
                data: data
            };
            series.push(seriesObject);
            drawPieChart(series);

            /* pie chart ends here */
        }
    });

    /* for pie chart */
    function drawPieChart(series){
        Highcharts.chart('chartContainer', {
            chart: {
                plotBackgroundColor: null,
                plotBorderWidth: null,
                plotShadow: false,
                type: 'pie'
            },
            title: {
                text: 'Browser market shares in January, 2018'
            },
            tooltip: {
                formatter: function() {
                    return '<strong>'+this.key+': </strong>'+ this.y;
                }
            },
            plotOptions: {
                pie: {
                    allowPointSelect: true,
                    cursor: 'pointer',
                    dataLabels: {
                        enabled: true,
                        format: '<b>{point.name}</b>: {point.y}'
                    }
                }
            },
            series: series
        });
    }

</script>

我的控制器

@GetMapping("/admin_home")
public String viewHomePage(){
 // Get list of course and count
        List<CountCourse> pieChart = dashBoardRepository.countCourseByCategory();

        model.addAttribute("pieChart",pieChart);
        return "Admin_Homepage";
}

我想要的只是将 catName、catCount 的值传递给饼图,但我不能 任何人帮助我。非常感谢。

【问题讨论】:

  • 这个问题我不清楚。 (1) admin_homepage.html 是否设置为 Thymeleaf 模板? (您已将该问题标记为 Thymeleaf 问题)。 (2) url: "admin_home" 在其 Ajax 响应中返回什么数据(以及以什么格式)?
  • 另外,请注意您的控制器中有return "Admin_Homepage";,它与您的 HTML 文件名中的“admin_homepage”不匹配。
  • @andrewJames 嗨,詹姆斯,感谢您的回复。 (1) 我的 admin_homepage.html 当然设置为 thymleaf 模板,我想在这个页面中创建一个饼图。我的饼图将包含课程名称和课程数量等数据。而这个数据输出就是饼图。我return "admin_homepage"匹配html文件名但没有帮助:((

标签: javascript spring spring-boot highcharts thymeleaf


【解决方案1】:

因为您使用的是 Thymeleaf 模板,所以您不需要使用 $.ajax({...}) 来检索饼图数据。相反,您可以将数据直接提供给 Thymeleaf 模板。

(或者,您可以继续使用 Ajax 调用 - 在这种情况下,Thymeleaf 模板将呈现为 HTML - 然后作为单独的步骤,Ajax 调用将获取饼图数据。)

以下假设是第一种方法(不需要 Ajax):

不需要 Ajax

我在问题中使用了您的 Thymeleaf 模板并对脚本进行了一些更改:

  1. 我删除了 Ajax 调用。

  2. 我添加了一个 Thymeleaf 变量来保存图表数据。

这是更新后的脚本:

<script th:inline="javascript">

    // this simply wraps the code in a function
    // that waits for the DOM to be ready:
    (function () {

        // this is populated by Thymeleaf:
        var pieChartData = /*[[${pieChartData}]]*/ [];

        var series = [];
        var data = [];

        for (var i = 0; i < pieChartData.length; i++) {
            var object = {};
            object.name = pieChartData[i].catName.toUpperCase();
            object.y = pieChartData[i].catCount;
            data.push(object);
        }
        var seriesObject = {
            name: 'Course By Category',
            colorByPoint: true,
            data: data
        };
        series.push(seriesObject);
        drawPieChart(series);

        // draw the pie chart:
        function drawPieChart(series) {
            Highcharts.chart('chartContainer', {
                chart: {
                    plotBackgroundColor: null,
                    plotBorderWidth: null,
                    plotShadow: false,
                    type: 'pie'
                },
                title: {
                    text: 'Your Heading Goes Here'
                },
                tooltip: {
                    formatter: function () {
                        return '<strong>' + this.key + ': </strong>' + this.y;
                    }
                },
                plotOptions: {
                    pie: {
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: true,
                            format: '<b>{point.name}</b>: {point.y}'
                        }
                    }
                },
                // use the series data defined earlier:
                series: series
            });
        }

    })();

</script>

关于这个脚本的要点是:

  1. 脚本标签如下所示:
<script th:inline="javascript">

这告诉 Thymeleaf 脚本将包含一个或多个 Thymeleaf 表达式。

在我们的例子中,我们有一个表达式 - 这里是:

var pieChartData = /*[[${pieChartData}]]*/ [];

此语法将导致 Thymeleaf 将 pieChartData 变量替换为 Java 控制器提供的数据结构。

这是来自控制器的片段:

List<CountCourse> pieChartData = dashBoardRepository.countCourseByCategory();
model.addAttribute("pieChartData", pieChartData);
return "admin_homepage";

这假设您有一个包含String catNameint catCountCountCourse 对象。

Thymeleaf 将获取 List&lt;CountCourse&gt; pieChartData 数据并为您生成以下 JavaScript(使用我的测试数据):

var pieChartData = [
  {"catName":"Humanities","catCount":123},
  {"catName":"Sciences","catCount":145},
  {"catName":"Other","catCount":67}
];

之后,我使用与您在 Ajax 成功函数中相同的逻辑将此原始数据转换为 HightCharts 饼图数据。

最终结果是以下 HTML 页面:

使用 Ajax

如果您想使用您的 Ajax 方法而不是这种方法,那么您需要构建一个单独的端点,它将饼图数据直接返回到 JavaScript 代码中的 Ajax 处理程序。

当您采用这种方法时,您不再需要使用 Thymeleaf 属性:

var pieChartData = /*[[${pieChartData}]]*/ []; // NO LONGER NEEDED

您不再需要将此数据传递给控制器​​中的模型:

model.addAttribute("pieChartData", pieChartData); // NO LONGER NEEDED

相反,您需要继续使用您的 $.ajax 代码,并且您需要构建一个单独的端点,该端点将 pieChartData 作为该 Ajax 调用的 JSON 返回:

$.ajax({
  /* for pie chart */
  url: "piechart_data_json", // some new URL for your JSON pie chart data
  ...
});

鉴于您已经在使用 Thymeleaf,我认为没有必要使用这种方法。


更新

只是为了多解释一下下面的语法:

var pieChartData = /*[[${pieChartData}]]*/ [];

它看起来像一个空的 JavaScript 数组 []。但事实上,还有更多。

Thymeleaf 变量${pieChartData} 接收来自控制器的数据。

因为变量位于&lt;script&gt; 标记中,仅使用标准Thymeleaf ${pieChartData} 表达式是不够的。您还必须用[[]] 包围该表达式。这是因为${pieChartData} 实际上是有效的 JavaScript - 例如,用于字符串插值。

这给了我们这个:

var pieChartData = [[${pieChartData}]];

这就是你所需要的。这将起作用。

这里的问题是,它不是有效的 JavaScript,因此您的 IDE 可能会突出显示它存在语法错误。

要解决此问题,您可以采取额外的步骤。您可以在 JavaScript 注释中“隐藏”表达式 - 然后提供有效值(空数组)。这可以让您的 IDE 中的 JavaScript 语法检查器满意。

Thymeleaf 将在该评论中找到变量并将其删除 - 并删除占位符 [] 值。

这就是 Thymeleaf 在这种情况下将 Java 模型数据推送到模板中的方式。

【讨论】:

  • 非常感谢我的朋友。我有一个小问题,当我们将数据从控制器传递到“pieChartData”时,我们在 html 中的哪里接收它?在javascript中,我只是看到您在初始化时为“pieChartData”留下了一个空数组。我不太明白从哪里获取这个控制器的数据。
  • 我添加了一些额外的注释来阐明它是如何工作的。
  • 非常感谢。我以为这是一个评论,但结果却是一个书面结构。非常感谢你帮我解决了我这几天的问题
  • 你好朋友,我来说我已经按照你的指示成功了。再来一次,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2020-03-24
  • 2017-06-26
  • 1970-01-01
  • 2017-04-14
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多