如何在HighCharts中实现Datatable列标题显示在Y轴上?
问题描述
我正在使用Datatables和HighCharts,希望实现年份显示在Y轴的柱状图,预期效果为:年份作为Y轴标签,对应数据以横向柱状图呈现。我是HighCharts新手,对其功能不太熟悉,请问如何实现该效果?
现有代码
HTML代码
<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" /> <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script> <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" /> <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script> <script src="https://code.highcharts.com/highcharts.js"></script> <meta charset=utf-8 /> </head> <body> <div id="container" style=" width: 100%; height: 400px;"></div> <div class="container"> <table id="example1" class="display nowrap" width="100%"><thead> <tr><th>Year</th><th>2012</th><th>2013</th><th>2014</th><th>2015</th><th>2016</th><th>2017</th><th>2018</th><th>2019</th><th>2020</th><th>2021</th></tr></thead> <tr ><td> Data</td><td>3,823</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr></tbody> </tbody></table> </body> </html>
JavaScript代码
$(document).ready(function() { var table = $("#example1").DataTable(); var salary = getSalaries(table); // Declare axis for the column graph var axis = { id: "salary", min: 0, title: { text: "Number" } }; // Declare inital series with the values from the getSalaries function var series = { name: "Overall", data: Object.values(salary) }; var myChart = Highcharts.chart("container", { chart: { type: "column" }, title: { text: "Test Data" }, xAxis: { categories: Object.keys(salary) }, yAxis: axis, series: [series] }); // On draw, get updated salaries and refresh axis and series table.on("draw", function() { salary = getSalaries(table); myChart.axes[0].categories = Object.keys(salary); myChart.series[0].setData(Object.values(salary)); }); }); function getSalaries(table) { var salaryCounts = {}; var salary = {}; // Get the row indexes for the rows displayed under the current search var indexes = table .rows({ search: "applied" }) .indexes() .toArray(); // For each row, extract the office and add the salary to the array for (var i = 0; i < indexes.length; i++) { var office = table.cell(indexes[i], 0).data(); if (salaryCounts[office] === undefined) { salaryCounts[office] = [+table.cell(indexes[i], 1).data().replace(/[^0-9.]/g, "")]; } else { salaryCounts[office].push(+table.cell(indexes[i], 1).data().replace(/[^0-9.]/g, "")); } } // Extract the office names that are present in the table var keys = Object.keys(salaryCounts); // For each office work out the average salary for (var i = 0; i < keys.length; i++) { var length = salaryCounts[keys[i]].length; var total = salaryCounts[keys[i]].reduce((a, b) => a + b, 0); salary[keys[i]] = total / length; } return salary; };
解决方案
要实现年份在Y轴的横向柱状图,需从三个核心点修改代码:
1. 调整HighCharts图表类型与轴配置
将图表类型从纵向柱状column改为横向柱状bar,并把年份类别移到Y轴,数值对应到X轴:
var myChart = Highcharts.chart("container", { chart: { type: "bar" // 切换为横向柱状图 }, title: { text: "年度数据统计" }, yAxis: { // Y轴放置年份类别 categories: Object.keys(salary), title: { text: "年份" } }, xAxis: axis, // X轴放置数值 series: [series] });
2. 重构数据提取函数getSalaries
原表格结构是表头为年份、数据行对应各年份数值,需重新编写逻辑直接提取表头年份和对应行的数值:
function getSalaries(table) { var salary = {}; // 获取表头的年份(跳过第一列"Year") var yearHeaders = table.columns().header().toArray().slice(1).map(header => $(header).text()); // 获取当前显示行的数据 var indexes = table.rows({ search: "applied" }).indexes().toArray(); if (indexes.length > 0) { var rowData = table.row(indexes[0]).data().slice(1); // 跳过第一列"Data" yearHeaders.forEach((year, index) => { // 格式化数值,去除逗号并转为数字 salary[year] = +rowData[index].replace(/[^0-9.]/g, ""); }); } return salary; };
3. 更新表格绘制后的图表刷新逻辑
轴配置变更后,刷新时需更新Y轴的类别,而非原X轴:
table.on("draw", function() { salary = getSalaries(table); myChart.yAxis[0].setCategories(Object.keys(salary)); myChart.series[0].setData(Object.values(salary)); });
完整修改后的JavaScript代码
$(document).ready(function() { var table = $("#example1").DataTable(); var salary = getSalaries(table); // 数值轴配置(原axis改为X轴) var axis = { id: "salary", min: 0, title: { text: "数值" } }; var series = { name: "数据", data: Object.values(salary) }; var myChart = Highcharts.chart("container", { chart: { type: "bar" }, title: { text: "年度数据统计" }, yAxis: { categories: Object.keys(salary), title: { text: "年份" } }, xAxis: axis, series: [series] }); table.on("draw", function() { salary = getSalaries(table); myChart.yAxis[0].setCategories(Object.keys(salary)); myChart.series[0].setData(Object.values(salary)); }); }); function getSalaries(table) { var salary = {}; var yearHeaders = table.columns().header().toArray().slice(1).map(header => $(header).text()); var indexes = table.rows({ search: "applied" }).indexes().toArray(); if (indexes.length > 0) { var rowData = table.row(indexes[0]).data().slice(1); yearHeaders.forEach((year, index) => { salary[year] = +rowData[index].replace(/[^0-9.]/g, ""); }); } return salary; };
优化后的HTML代码(去除重复资源引入)
<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" /> <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script> <script src="https://code.highcharts.com/highcharts.js"></script> <meta charset=utf-8 /> </head> <body> <div id="container" style="width: 100%; height: 400px;"></div> <div class="container"> <table id="example1" class="display nowrap" width="100%"> <thead> <tr> <th>Year</th> <th>2012</th> <th>2013</th> <th>2014</th> <th>2015</th> <th>2016</th> <th>2017</th> <th>2018</th> <th>2019</th> <th>2020</th> <th>2021</th> </tr> </thead> <tbody> <tr> <td> Data</td> <td>3,823</td> <td>3,823</td> <td>3,954</td> <td>3,959</td> <td>3,955</td> <td>3,956</td> <td>3,843</td> <td>3,699</td> <td>3,472</td> <td>3,551</td> </tr> </tbody> </table> </div> </body> </html>
内容的提问来源于stack exchange,提问作者magicsinger
相关产品推荐
相关产品推荐

