使用 spring boot, thymeleaf, js, highchart 绘制饼图但不能
Draw pie chart using spring boot, thymeleaf, js, highchart but can't
我是 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 的值传递给饼图,但我做不到
任何人帮助我。非常感谢。
因为您使用的是 Thymeleaf 模板,所以您不需要使用 $.ajax({...})
来检索饼图数据。相反,您可以直接向 Thymeleaf 模板提供数据。
(或者,您可以继续使用 Ajax 调用 - 在这种情况下,Thymeleaf 模板将呈现为 HTML - 然后作为单独的步骤,Ajax 调用将获取饼图数据。)
以下假定第一种方法(不需要 Ajax):
不需要Ajax
我在问题中使用了您的 Thymeleaf 模板并对脚本进行了一些更改:
我删除了 Ajax 调用。
我添加了一个 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>
这个脚本的要点是:
- 脚本标签如下所示:
<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 catName
和 int catCount
的 CountCourse
对象。
Thymeleaf 将获取 List<CountCourse> pieChartData
数据并为您生成以下 Java 脚本(使用我的测试数据):
var pieChartData = [
{"catName":"Humanities","catCount":123},
{"catName":"Sciences","catCount":145},
{"catName":"Other","catCount":67}
];
之后,我使用与您在 Ajax 成功函数中相同的逻辑将此原始数据转换为 HightCharts 饼图数据。
最终结果如下 HTML 页:
和Ajax
如果你想使用你的 Ajax 方法而不是这个,那么你需要构建一个单独的端点,它将 return 饼图数据直接发送到 Ajax 处理程序在你的Java脚本代码中。
当您采用这种方法时,您不再需要使用 Thymeleaf 属性:
var pieChartData = /*[[${pieChartData}]]*/ []; // NO LONGER NEEDED
并且您不再需要将此数据传递给控制器中的模型:
model.addAttribute("pieChartData", pieChartData); // NO LONGER NEEDED
相反,您需要继续使用您的 $.ajax
代码,并且您需要构建一个单独的端点,其中 return 将 pieChartData
作为 JSON Ajax 通话:
$.ajax({
/* for pie chart */
url: "piechart_data_json", // some new URL for your JSON pie chart data
...
});
鉴于您已经在使用 Thymeleaf,我认为没有必要使用这种方法。
更新
只是稍微解释一下下面的语法:
var pieChartData = /*[[${pieChartData}]]*/ [];
它看起来像一个空的 Java脚本数组 []
。但事实上,还有更多。
Thymeleaf 变量 ${pieChartData}
从控制器接收数据。
因为变量位于 <script>
标记中,仅使用标准的 Thymeleaf ${pieChartData}
表达式是不够的。您还必须用 [[
和 ]]
包围该表达式。这是因为 ${pieChartData}
实际上是有效的 Java 脚本 - 例如,用于字符串插值。
这给了我们这个:
var pieChartData = [[${pieChartData}]];
这就是您所需要的。这会起作用。
这里的问题是,它不是有效的 Java脚本,因此您的 IDE 可能会突出显示它存在语法错误。
要解决此问题,您可以采取额外的步骤。您可以在 Java 脚本注释中“隐藏”表达式 - 然后提供有效值(空数组)。这使 JavaScript 语法检查器在您的 IDE.
中保持快乐
Thymeleaf 将在该注释中找到变量并将其删除 - 同时删除占位符 []
值。
在这种情况下,这就是 Thymeleaf 将 Java 模型数据推送到模板中的方式。
我是 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 的值传递给饼图,但我做不到 任何人帮助我。非常感谢。
因为您使用的是 Thymeleaf 模板,所以您不需要使用 $.ajax({...})
来检索饼图数据。相反,您可以直接向 Thymeleaf 模板提供数据。
(或者,您可以继续使用 Ajax 调用 - 在这种情况下,Thymeleaf 模板将呈现为 HTML - 然后作为单独的步骤,Ajax 调用将获取饼图数据。)
以下假定第一种方法(不需要 Ajax):
不需要Ajax
我在问题中使用了您的 Thymeleaf 模板并对脚本进行了一些更改:
我删除了 Ajax 调用。
我添加了一个 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>
这个脚本的要点是:
- 脚本标签如下所示:
<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 catName
和 int catCount
的 CountCourse
对象。
Thymeleaf 将获取 List<CountCourse> pieChartData
数据并为您生成以下 Java 脚本(使用我的测试数据):
var pieChartData = [
{"catName":"Humanities","catCount":123},
{"catName":"Sciences","catCount":145},
{"catName":"Other","catCount":67}
];
之后,我使用与您在 Ajax 成功函数中相同的逻辑将此原始数据转换为 HightCharts 饼图数据。
最终结果如下 HTML 页:
和Ajax
如果你想使用你的 Ajax 方法而不是这个,那么你需要构建一个单独的端点,它将 return 饼图数据直接发送到 Ajax 处理程序在你的Java脚本代码中。
当您采用这种方法时,您不再需要使用 Thymeleaf 属性:
var pieChartData = /*[[${pieChartData}]]*/ []; // NO LONGER NEEDED
并且您不再需要将此数据传递给控制器中的模型:
model.addAttribute("pieChartData", pieChartData); // NO LONGER NEEDED
相反,您需要继续使用您的 $.ajax
代码,并且您需要构建一个单独的端点,其中 return 将 pieChartData
作为 JSON Ajax 通话:
$.ajax({
/* for pie chart */
url: "piechart_data_json", // some new URL for your JSON pie chart data
...
});
鉴于您已经在使用 Thymeleaf,我认为没有必要使用这种方法。
更新
只是稍微解释一下下面的语法:
var pieChartData = /*[[${pieChartData}]]*/ [];
它看起来像一个空的 Java脚本数组 []
。但事实上,还有更多。
Thymeleaf 变量 ${pieChartData}
从控制器接收数据。
因为变量位于 <script>
标记中,仅使用标准的 Thymeleaf ${pieChartData}
表达式是不够的。您还必须用 [[
和 ]]
包围该表达式。这是因为 ${pieChartData}
实际上是有效的 Java 脚本 - 例如,用于字符串插值。
这给了我们这个:
var pieChartData = [[${pieChartData}]];
这就是您所需要的。这会起作用。
这里的问题是,它不是有效的 Java脚本,因此您的 IDE 可能会突出显示它存在语法错误。
要解决此问题,您可以采取额外的步骤。您可以在 Java 脚本注释中“隐藏”表达式 - 然后提供有效值(空数组)。这使 JavaScript 语法检查器在您的 IDE.
中保持快乐Thymeleaf 将在该注释中找到变量并将其删除 - 同时删除占位符 []
值。
在这种情况下,这就是 Thymeleaf 将 Java 模型数据推送到模板中的方式。