在 Highcharts 底部配置数据 Table
Configure Data Table at bottom in Highcharts
我们将 Higcharts 库用于我们的图表,并希望在图表下方的 table 中淡入和淡出数据。我找到了一些代码部分来定义 table 在 javaScript 本身中的数据外观,但在一些配置方面遇到了困难,如定义:
- 小数位数
- 去掉table
中第二行的粗体字
因为我的 javaScript-技能相当有限。
这里是我的例子:https://jsfiddle.net/BlackLabel/bs12atdq/
var H = Highcharts,
{
pick,
fireEvent
} = H,
htmlencode = function(html) {
return html
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
H.Chart.prototype.getTable = function(useLocalDecimalPoint) {
var html = '<table id="highcharts-data-table-' + this.index + '">',
options = this.options,
decimalPoint = useLocalDecimalPoint ? (1.1).toLocaleString()[1] : '.',
useMultiLevelHeaders = pick(options.exporting.useMultiLevelHeaders, true),
rows = this.getDataRows(useMultiLevelHeaders),
rowLength = 0,
topHeaders = useMultiLevelHeaders ? rows.shift() : null,
subHeaders = rows.shift(),
// Compare two rows for equality
isRowEqual = function(row1, row2) {
var i = row1.length;
if (row2.length === i) {
while (i--) {
if (row1[i] !== row2[i]) {
return false;
}
}
} else {
return false;
}
return true;
},
// Get table cell HTML from value
getCellHTMLFromValue = function(tag, classes, attrs, value) {
var val = pick(value, ''),
className = 'text' + (classes ? ' ' + classes : '');
// Convert to string if number
if (typeof val === 'number') {
//-------------------------------------------------------
val = H.numberFormat(val, null, null, ',');
//-------------------------------------------------------
val = val.toString();
if (decimalPoint === ',') {
val = val.replace('.', decimalPoint);
}
className = 'number';
} else if (!value) {
className = 'empty';
}
return '<' + tag + (attrs ? ' ' + attrs : '') +
' class="' + className + '">' +
val + '</' + tag + '>';
},
// Get table header markup from row data
getTableHeaderHTML = function(topheaders, subheaders, rowLength) {
var html = '<thead>',
i = 0,
len = rowLength || subheaders && subheaders.length,
next,
cur,
curColspan = 0,
rowspan;
// Clean up multiple table headers. Chart.getDataRows() returns two
// levels of headers when using multilevel, not merged. We need to
// merge identical headers, remove redundant headers, and keep it
// all marked up nicely.
if (useMultiLevelHeaders &&
topheaders &&
subheaders &&
!isRowEqual(topheaders, subheaders)) {
html += '<tr>';
for (; i < len; ++i) {
cur = topheaders[i];
next = topheaders[i + 1];
if (cur === next) {
++curColspan;
} else if (curColspan) {
// Ended colspan
// Add cur to HTML with colspan.
html += getCellHTMLFromValue('th', 'highcharts-table-topheading', 'scope="col" ' +
'colspan="' + (curColspan + 1) + '"', cur);
curColspan = 0;
} else {
// Cur is standalone. If it is same as sublevel,
// remove sublevel and add just toplevel.
if (cur === subheaders[i]) {
if (options.exporting.useRowspanHeaders) {
rowspan = 2;
delete subheaders[i];
} else {
rowspan = 1;
subheaders[i] = '';
}
} else {
rowspan = 1;
}
html += getCellHTMLFromValue('th', 'highcharts-table-topheading', 'scope="col"' +
(rowspan > 1 ?
' valign="top" rowspan="' + rowspan + '"' :
''), cur);
}
}
html += '</tr>';
}
// Add the subheaders (the only headers if not using multilevels)
if (subheaders) {
html += '<tr>';
for (i = 0, len = subheaders.length; i < len; ++i) {
if (typeof subheaders[i] !== 'undefined') {
html += getCellHTMLFromValue('th', null, 'scope="col"', subheaders[i]);
}
}
html += '</tr>';
}
html += '</thead>';
return html;
};
// Find longest row
for (var i = 0, len = rows.length; i < len; ++i) {
if (rows[i].length > rowLength) {
rowLength = rows[i].length;
}
}
// Add header
html += getTableHeaderHTML(topHeaders, subHeaders, Math.max(rowLength, subHeaders.length));
// Transform the rows to HTML
html += '<tbody>';
rows.forEach(function(row) {
html += '<tr>';
for (var j = 0; j < rowLength; j++) {
// Make first column a header too. Especially important for
// category axes, but also might make sense for datetime? Should
// await user feedback on this.
html += getCellHTMLFromValue(j ? 'td' : 'th', null, j ? '' : 'scope="row"', row[j]);
}
html += '</tr>';
});
html += '</tbody></table>';
var e = {
html: html
};
fireEvent(this, 'afterGetTable', e);
return e.html;
};
$(document).ready(function() {
var chart = {
type: 'line'
};
var plotOptions = {
line: {
marker: {
enabled: false
}
}
};
var title = {
text: 'title',
style: {
fontSize: '18px'
},
align: 'left'
};
var subtitle = {
text: 'subtitle',
style: {
fontSize: '12px'
},
align: 'left'
};
var yAxis = {
gridLineWidth: 0,
plotLines: [{
color: "#ccd6eb",
value: 0,
width: 2
}],
lineWidth: 1,
title: ''
};
var xAxis = {
categories: [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020],
rotation: -90,
align: 'left'
};
var legend = {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
padding: 25,
symbolPadding: 10,
symbolWidth: 25,
margin: -10,
itemStyle: {
fontWeight: 'normal'
}
};
var tooltip = {
pointFormat: '{series.name}: <b>{point.y:,.1f} %',
shared: false
};
var series = [{
name: 'Group 1',
color: '#3CA433',
data: [-0.9, -0.7, -0.4, 0.2, 0.2, 0.5, 0.7, 0.5, 0.9, 0.8, 1.0]
}, {
name: 'Group 2',
color: '#0064e6',
data: [1.4, 1.7, 1.8, 1.5, 1.4, 1.1, 1.0, 0.8, 0.5, 0.7, 0.7]
}, {
name: 'Group 3',
color: '#27408B',
data: [2.8, 3.3, 3.3, 3.0, 3.2, 3.2, 2.6, 3.0, 3.0, 3.1, 3.1]
}];
var credits = {
text: 'Source',
href: false,
style: {
color: '#999999',
cursor: false,
fontSize: '10px'
},
position: {
align: 'left',
x: 10,
y: -20
}
};
var exporting = {
allowHTML: true,
enabled: true,
showTable: true,
filename: 'Linechart_Example',
buttons: {
contextButton: {
menuItems: "printChart separator downloadPNG downloadJPEG downloadSVG separator downloadXLS".split(" ")
}
},
/*csv: {
columnHeaderFormatter: function (item) {
if(item instanceof Highcharts.Axis) {
return 'Quartal';
} else {
if(item instanceof Highcharts.Series) {
return item.name;
}
}
}
}*/
};
var highchartsOptions = Highcharts.setOptions({
lang: {
decimalPoint: '.',
thousandsSep: "'",
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
contextButtonTitle: 'Drucken, Download, Export',
downloadJPEG: 'Download JPEG Bild',
downloadPNG: 'Download PNG Bild',
downloadSVG: 'Download SVG Vektor Bild',
downloadXLS: 'Download XLS',
printChart: 'Bild drucken',
viewData: 'Datentabelle ein-/ausblenden',
resetZoom: "Zoom zurücksetzen",
resetZoomTitle: "Zoom zurücksetzen",
drillUpText: "Zurück"
}
});
var json = {};
json.chart = chart;
json.title = title;
json.subtitle = subtitle;
json.yAxis = yAxis;
json.xAxis = xAxis;
json.series = series;
json.tooltip = tooltip;
json.legend = legend;
json.credits = credits;
json.exporting = exporting;
json.plotOptions = plotOptions;
json.highchartsOptions = highchartsOptions;
$('#Linechart_Example').highcharts(json);
}); ```
Thanks for any help.
要编辑小数位数,请更改 numberFormat
方法中的参数。
val = H.numberFormat(val, null, null, ',');
将 font-weight: normal
样式添加到创建的 th
标签。
for (i = 0, len = subheaders.length; i < len; ++i) {
if (typeof subheaders[i] !== 'undefined') {
html += getCellHTMLFromValue('th', null, 'scope="col"' + ' style="font-weight: normal;"', subheaders[i]);
}
}
现场演示: https://jsfiddle.net/BlackLabel/1k4L5gd8/
API参考:https://api.highcharts.com/class-reference/Highcharts#.numberFormat
我们将 Higcharts 库用于我们的图表,并希望在图表下方的 table 中淡入和淡出数据。我找到了一些代码部分来定义 table 在 javaScript 本身中的数据外观,但在一些配置方面遇到了困难,如定义:
- 小数位数
- 去掉table 中第二行的粗体字
因为我的 javaScript-技能相当有限。
这里是我的例子:https://jsfiddle.net/BlackLabel/bs12atdq/
var H = Highcharts,
{
pick,
fireEvent
} = H,
htmlencode = function(html) {
return html
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
H.Chart.prototype.getTable = function(useLocalDecimalPoint) {
var html = '<table id="highcharts-data-table-' + this.index + '">',
options = this.options,
decimalPoint = useLocalDecimalPoint ? (1.1).toLocaleString()[1] : '.',
useMultiLevelHeaders = pick(options.exporting.useMultiLevelHeaders, true),
rows = this.getDataRows(useMultiLevelHeaders),
rowLength = 0,
topHeaders = useMultiLevelHeaders ? rows.shift() : null,
subHeaders = rows.shift(),
// Compare two rows for equality
isRowEqual = function(row1, row2) {
var i = row1.length;
if (row2.length === i) {
while (i--) {
if (row1[i] !== row2[i]) {
return false;
}
}
} else {
return false;
}
return true;
},
// Get table cell HTML from value
getCellHTMLFromValue = function(tag, classes, attrs, value) {
var val = pick(value, ''),
className = 'text' + (classes ? ' ' + classes : '');
// Convert to string if number
if (typeof val === 'number') {
//-------------------------------------------------------
val = H.numberFormat(val, null, null, ',');
//-------------------------------------------------------
val = val.toString();
if (decimalPoint === ',') {
val = val.replace('.', decimalPoint);
}
className = 'number';
} else if (!value) {
className = 'empty';
}
return '<' + tag + (attrs ? ' ' + attrs : '') +
' class="' + className + '">' +
val + '</' + tag + '>';
},
// Get table header markup from row data
getTableHeaderHTML = function(topheaders, subheaders, rowLength) {
var html = '<thead>',
i = 0,
len = rowLength || subheaders && subheaders.length,
next,
cur,
curColspan = 0,
rowspan;
// Clean up multiple table headers. Chart.getDataRows() returns two
// levels of headers when using multilevel, not merged. We need to
// merge identical headers, remove redundant headers, and keep it
// all marked up nicely.
if (useMultiLevelHeaders &&
topheaders &&
subheaders &&
!isRowEqual(topheaders, subheaders)) {
html += '<tr>';
for (; i < len; ++i) {
cur = topheaders[i];
next = topheaders[i + 1];
if (cur === next) {
++curColspan;
} else if (curColspan) {
// Ended colspan
// Add cur to HTML with colspan.
html += getCellHTMLFromValue('th', 'highcharts-table-topheading', 'scope="col" ' +
'colspan="' + (curColspan + 1) + '"', cur);
curColspan = 0;
} else {
// Cur is standalone. If it is same as sublevel,
// remove sublevel and add just toplevel.
if (cur === subheaders[i]) {
if (options.exporting.useRowspanHeaders) {
rowspan = 2;
delete subheaders[i];
} else {
rowspan = 1;
subheaders[i] = '';
}
} else {
rowspan = 1;
}
html += getCellHTMLFromValue('th', 'highcharts-table-topheading', 'scope="col"' +
(rowspan > 1 ?
' valign="top" rowspan="' + rowspan + '"' :
''), cur);
}
}
html += '</tr>';
}
// Add the subheaders (the only headers if not using multilevels)
if (subheaders) {
html += '<tr>';
for (i = 0, len = subheaders.length; i < len; ++i) {
if (typeof subheaders[i] !== 'undefined') {
html += getCellHTMLFromValue('th', null, 'scope="col"', subheaders[i]);
}
}
html += '</tr>';
}
html += '</thead>';
return html;
};
// Find longest row
for (var i = 0, len = rows.length; i < len; ++i) {
if (rows[i].length > rowLength) {
rowLength = rows[i].length;
}
}
// Add header
html += getTableHeaderHTML(topHeaders, subHeaders, Math.max(rowLength, subHeaders.length));
// Transform the rows to HTML
html += '<tbody>';
rows.forEach(function(row) {
html += '<tr>';
for (var j = 0; j < rowLength; j++) {
// Make first column a header too. Especially important for
// category axes, but also might make sense for datetime? Should
// await user feedback on this.
html += getCellHTMLFromValue(j ? 'td' : 'th', null, j ? '' : 'scope="row"', row[j]);
}
html += '</tr>';
});
html += '</tbody></table>';
var e = {
html: html
};
fireEvent(this, 'afterGetTable', e);
return e.html;
};
$(document).ready(function() {
var chart = {
type: 'line'
};
var plotOptions = {
line: {
marker: {
enabled: false
}
}
};
var title = {
text: 'title',
style: {
fontSize: '18px'
},
align: 'left'
};
var subtitle = {
text: 'subtitle',
style: {
fontSize: '12px'
},
align: 'left'
};
var yAxis = {
gridLineWidth: 0,
plotLines: [{
color: "#ccd6eb",
value: 0,
width: 2
}],
lineWidth: 1,
title: ''
};
var xAxis = {
categories: [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020],
rotation: -90,
align: 'left'
};
var legend = {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
padding: 25,
symbolPadding: 10,
symbolWidth: 25,
margin: -10,
itemStyle: {
fontWeight: 'normal'
}
};
var tooltip = {
pointFormat: '{series.name}: <b>{point.y:,.1f} %',
shared: false
};
var series = [{
name: 'Group 1',
color: '#3CA433',
data: [-0.9, -0.7, -0.4, 0.2, 0.2, 0.5, 0.7, 0.5, 0.9, 0.8, 1.0]
}, {
name: 'Group 2',
color: '#0064e6',
data: [1.4, 1.7, 1.8, 1.5, 1.4, 1.1, 1.0, 0.8, 0.5, 0.7, 0.7]
}, {
name: 'Group 3',
color: '#27408B',
data: [2.8, 3.3, 3.3, 3.0, 3.2, 3.2, 2.6, 3.0, 3.0, 3.1, 3.1]
}];
var credits = {
text: 'Source',
href: false,
style: {
color: '#999999',
cursor: false,
fontSize: '10px'
},
position: {
align: 'left',
x: 10,
y: -20
}
};
var exporting = {
allowHTML: true,
enabled: true,
showTable: true,
filename: 'Linechart_Example',
buttons: {
contextButton: {
menuItems: "printChart separator downloadPNG downloadJPEG downloadSVG separator downloadXLS".split(" ")
}
},
/*csv: {
columnHeaderFormatter: function (item) {
if(item instanceof Highcharts.Axis) {
return 'Quartal';
} else {
if(item instanceof Highcharts.Series) {
return item.name;
}
}
}
}*/
};
var highchartsOptions = Highcharts.setOptions({
lang: {
decimalPoint: '.',
thousandsSep: "'",
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
contextButtonTitle: 'Drucken, Download, Export',
downloadJPEG: 'Download JPEG Bild',
downloadPNG: 'Download PNG Bild',
downloadSVG: 'Download SVG Vektor Bild',
downloadXLS: 'Download XLS',
printChart: 'Bild drucken',
viewData: 'Datentabelle ein-/ausblenden',
resetZoom: "Zoom zurücksetzen",
resetZoomTitle: "Zoom zurücksetzen",
drillUpText: "Zurück"
}
});
var json = {};
json.chart = chart;
json.title = title;
json.subtitle = subtitle;
json.yAxis = yAxis;
json.xAxis = xAxis;
json.series = series;
json.tooltip = tooltip;
json.legend = legend;
json.credits = credits;
json.exporting = exporting;
json.plotOptions = plotOptions;
json.highchartsOptions = highchartsOptions;
$('#Linechart_Example').highcharts(json);
}); ```
Thanks for any help.
要编辑小数位数,请更改
numberFormat
方法中的参数。val = H.numberFormat(val, null, null, ',');
将
font-weight: normal
样式添加到创建的th
标签。for (i = 0, len = subheaders.length; i < len; ++i) { if (typeof subheaders[i] !== 'undefined') { html += getCellHTMLFromValue('th', null, 'scope="col"' + ' style="font-weight: normal;"', subheaders[i]); } }
现场演示: https://jsfiddle.net/BlackLabel/1k4L5gd8/
API参考:https://api.highcharts.com/class-reference/Highcharts#.numberFormat