Highcharts Highstock |工具提示置换|工具提示内容拾取前一天';放大时在当前工具提示上显示数据
预期行为 即使内容被放大或缩小,特定日期的工具提示内容也应保持不变 实际行为 放大和缩小图形时,同一天的工具提示内容不同 带复制步骤的现场演示 Github问题链接 受影响的浏览器 Firefox/Chrome 说明 检查2016年6月4日的工具提示内容,然后将日期从范围选择器更改为2016年6月1日至2016年6月30日,鼠标悬停至6月4日工具提示,现在工具提示具有不同的内容。我的代码有问题,或者可能在Highchart的末尾,我无法找出原因 代码在下面Highcharts Highstock |工具提示置换|工具提示内容拾取前一天';放大时在当前工具提示上显示数据,highcharts,highstock,Highcharts,Highstock,预期行为 即使内容被放大或缩小,特定日期的工具提示内容也应保持不变 实际行为 放大和缩小图形时,同一天的工具提示内容不同 带复制步骤的现场演示 Github问题链接 受影响的浏览器 Firefox/Chrome 说明 检查2016年6月4日的工具提示内容,然后将日期从范围选择器更改为2016年6月1日至2016年6月30日,鼠标悬停至6月4日工具提示,现在工具提示具有不同的内容。我的代码有问题,或者可能在Highchart的末尾,我无法找出原因 代码在下面 var seriesOptions
var seriesOptions = [];
$(function() {
var html = '';
var groupingButtons = {
"Day": "day",
"Week": "week",
"Month":"month",
"3M":"quater",
"6M":"half"
};
for (var i in groupingButtons) {
html += '<button class="btn btn-default dateWiseCriteria" data-criteria="' + groupingButtons[i] + '">' + i + '</button>';
}
$('.dateWiseCriteriaContainer').html(html);
var options = {};
$.extend(options, {
units: [
['week', [1]]
]
});
drawAnalyticalStockChart(getSeries(), options);
$(document).on('click', '.dateWiseCriteria', function() {
var options = {};
var criteria = $(this).data('criteria') == 'quater' ? 'month' : $(this).data('criteria');
criteria = $(this).data('criteria') == 'half' ? 'month' : criteria;
var value = $(this).data('criteria') == 'quater' ? 3 : 1;
value = $(this).data('criteria') == 'half' ? 6 : value;
$.extend(options, {
units: [
[criteria, [value]]
]
});
drawAnalyticalStockChart(getSeries(), options);
});
});
function drawAnalyticalStockChart(series, options) {
Highcharts.stockChart('container', {
chart: {
zoomType: 'x',
},
credits: {
enabled: false
},
rangeSelector: {
selected: 4
},
legend: {
enabled: true
},
scrollbar: {
showFull: false
},
xAxis: [{
crosshair: true,
}],
yAxis: [{ // Primary yAxis
type: 'datetime',
dateTimeLabelFormats: { //force all formats to be hour:minute:second
second: '%H:%M:%S',
minute: '%H:%M:%S',
hour: '%H:%M:%S',
day: '%H:%M:%S',
week: '%H:%M:%S',
month: '%H:%M:%S',
year: '%H:%M:%S'
},
labels: {
formatter: function() {
//get the timestamp
var time = this.value;
return _format_date(time, 1);
//now manipulate the timestamp as you wan using data functions
},
style: {
color: Highcharts.getOptions().colors[2]
},
x: 42
},
title: {
text: 'Average Resolution Time',
style: {
color: Highcharts.getOptions().colors[2]
},
margin: 53
},
opposite: true
}, { // Secondary yAxis
gridLineWidth: 0,
title: {
text: 'Cases',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} Cases',
style: {
color: Highcharts.getOptions().colors[0]
}
},
allowDecimals: false,
opposite: false
}, { // Tertiary yAxis
gridLineWidth: 0,
title: {
text: 'Average Response Time',
style: {
color: Highcharts.getOptions().colors[3]
}
},
labels: {
formatter: function() {
//get the timestamp
var time = this.value;
return _format_date(time, 0, 1);
//now manipulate the timestamp as you wan using data functions
},
style: {
color: Highcharts.getOptions().colors[3]
}
},
type: 'datetime',
dateTimeLabelFormats: { //force all formats to be hour:minute:second
second: '%H:%M:%S',
minute: '%H:%M:%S',
hour: '%H:%M:%S',
day: '%H:%M:%S',
week: '%H:%M:%S',
month: '%H:%M:%S',
year: '%H:%M:%S'
},
}],
tooltip: {
formatter: function() {
var points = this.points;
var groupingFormat = points[0].series.options.dataGrouping.dateTimeLabelFormats[points[0].series.currentDataGrouping.unitName][0];
var headerFormat = '<span style="font-size: 10px">' + Highcharts.dateFormat(groupingFormat, this.x) + '</span><br/>';
var pointFormat = '',
currentYear;
var isAllPointsHaveData = [];
points.forEach(function(point) {
if(point.y > 0) {
isAllPointsHaveData.push(1);
}
});
points.forEach(function(point) {
var name = point.series.name,
part;
var finalValue = point.y;
var showOnTooltip = true;
if (name === 'Current Year') {
currentYear = part = new Date(point.x).getFullYear();
} else if (name === 'Previous Year') {
part = new Date(point.x).getFullYear() - 1
} else if (name === 'Average Response Time') {
finalValue = _format_date(point.y, 0, 1, 1);
part = (typeof currentYear !== 'undefined' ? name + ' ('+currentYear+')' : name );
} else {
finalValue = _format_date(point.y, 1, 1, 1);
part = (typeof currentYear !== 'undefined' ? name + ' ('+currentYear+')' : name );
}
if(!$.isEmptyObject(isAllPointsHaveData)) {
pointFormat += '<span style="color:' + point.color + '">\u25CF</span> <p style="color:' + point.color + '">' + part + '</p>: <b>' + finalValue + ' ' + point.series.tooltipOptions.valueSuffix + '</b><br/>';
}
});
return headerFormat + pointFormat;
},
},
plotOptions: {
series: {
showInNavigator: true,
dataGrouping: {
dateTimeLabelFormats: {
millisecond: ['%A, %b %e, %H:%M:%S.%L', '%A, %b %e, %H:%M:%S.%L', '-%H:%M:%S.%L'],
second: ['%A, %b %e, %H:%M:%S', '%A, %b %e, %H:%M:%S', '-%H:%M:%S'],
minute: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
hour: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
day: ['%A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
week: ['Week from %A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
month: ['%B %Y', '%B', '-%B %Y'],
year: ['%Y', '%Y', '-%Y']
},
enabled: true,
forced: true,
units: options.units,
smoothed: true,
}
}
},
series: getSeries()
});
}
function getSeries() {
seriesOptions = [{
name: 'Previous Year',
type: 'column',
yAxis: 1,
tooltip: {
valueSuffix: ' Case(s)',
},
data: [],
"dataGrouping": {
"approximation": "sum"
},
"color": "#8085E9"
}, {
name: 'Current Year',
type: 'column',
yAxis: 1,
tooltip: {
valueSuffix: ' Case(s)',
},
data: [],
"dataGrouping": {
"approximation": "sum"
},
"color": "#F45B5B"
}, {
name: 'Average Response Time',
type: 'spline',
yAxis: 2,
tooltip: {
valueSuffix: '',
},
data: [],
"dataGrouping": {
approximation: function(arr) {
var groupedData = [];
var xyDataWithTimestamps = [];
var t = this;
this.xData.forEach(function(xd, i) {
xyDataWithTimestamps.push([
xd,
t.yData[i]
]);
});
var groupedDataWithTimestamps = [];
for(var i in arr) {
var arr1 = jQuery.grep(xyDataWithTimestamps, function( a ) {
return a[1] == arr[i];
});
groupedDataWithTimestamps.push([
arr1[0][0],
arr1[0][1]
]);
}
var len = arr.length;
var seconds = [], cases = [];
var finalArrayWithData = [];
for(var i in groupedDataWithTimestamps) {
if(groupedDataWithTimestamps[i][1] > 0) {
var date = _format_date(arr[i], 1, 1, 1, true);
seconds.push((((date.d * 24) * 60) * 60) + ((date.h * 60) * 60) + (date.m * 60));
var arr2 = jQuery.grep(seriesOptions[1].data, function( a ) {
return a[0] == groupedDataWithTimestamps[i][0];
});
cases.push(arr2[0][1]);
finalArrayWithData['s'] = seconds;
finalArrayWithData['cases'] = cases;
}
}
var sumTopS = 0;
var sumBottom = 0;
console.log(finalArrayWithData);
for (var i in finalArrayWithData['cases']) {
if(finalArrayWithData['s'][i] > 0) {
sumTopS += finalArrayWithData['cases'][i] * finalArrayWithData['s'][i];
sumBottom += finalArrayWithData['cases'][i];
}
}
var averageS = 0;
if ($.isNumeric(sumTopS) && sumBottom) {
averageS = Math.round(sumTopS / sumBottom);
}
_dts = Date.UTC(1970, 0, 1, 0, 0, averageS) / 1000;
return _dts;
}
},
"color": "#8BA6C7"
}];
return seriesOptions;
}
function _format_date(ts, d = 0, h = 0, m = 0, getArray = false) {
var date_now = 0;
var label = '';
var date_future = ts * 1000;
var dateArray = [];
// get total seconds between the times
var delta = Math.abs(date_future - date_now) / 1000;
// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
var finalValue = '';
if (d) {
label = days > 1 ? ' days ' : ' day ';
dateArray['d'] = days;
finalValue += days + label;
}
delta -= days * 86400;
// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
if (h) {
if (d == 0) {
var totalHours = hours + (days * 24);
label = totalHours > 1 ? ' hours ' : ' hour ';
dateArray['h'] = totalHours;
finalValue += totalHours + label;
} else {
label = hours > 1 ? ' hours ' : ' hour ';
dateArray['h'] = hours;
finalValue += hours + label;
}
}
// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;
if (m) {
label = minutes > 1 ? ' minutes ' : ' minute ';
dateArray['m'] = minutes;
finalValue += minutes + label;
}
if(getArray) {
return dateArray;
}
return finalValue;
}
var系列选项=[];
$(函数(){
var html='';
变量分组按钮={
“日”:“日”,
“周”:“周”,
“月”:“月”,
“3M”:“四分之一”,
“6M”:“一半”
};
用于(分组按钮中的变量i){
html+=''+i+'';
}
$('.dateWiseCriteriaContainer').html(html);
var选项={};
$.extend(选项{
单位:[
[‘周’,[1]]
]
});
drawAnalyticalStockChart(getSeries(),选项);
$(文档).on('单击','.dateWiseCriteria',函数(){
var选项={};
变量标准=$(此).data('criteria')=='quater'?'month':$(此).data('criteria');
条件=$(this).data('criteria')=='half'?'month':条件;
var值=$(this).data('criteria')=='quater'?3:1;
值=$(this).data('criteria')=='half'?6:值;
$.extend(选项{
单位:[
[标准,[值]]
]
});
drawAnalyticalStockChart(getSeries(),选项);
});
});
函数图AnalyticalStockChart(系列,选项){
Highcharts.stockChart(‘容器’{
图表:{
zoomType:'x',
},
学分:{
已启用:false
},
范围选择器:{
选定:4
},
图例:{
已启用:true
},
滚动条:{
炫耀:假
},
xAxis:[{
十字准星:没错,
}],
yAxis:[{//主yAxis
键入:“日期时间”,
dateTimeLabelFormats:{//强制所有格式为小时:分钟:秒
第二个:“%H:%M:%S”,
分钟:“%H:%M:%S”,
小时数:“%H:%M:%S”,
日期:“%H:%M:%S”,
周:“%H:%M:%S”,
月份:“%H:%M:%S”,
年份:'%H:%M:%S'
},
标签:{
格式化程序:函数(){
//获取时间戳
var时间=该值;
返回格式日期(时间,1);
//现在,在使用数据函数时操纵时间戳
},
风格:{
颜色:Highcharts.getOptions().colors[2]
},
x:42
},
标题:{
文本:“平均解析时间”,
风格:{
颜色:Highcharts.getOptions().colors[2]
},
差额:53
},
相反:对
},{//次雅克西
网格线宽:0,
标题:{
正文:“案例”,
风格:{
颜色:Highcharts.getOptions().color[0]
}
},
标签:{
格式:“{value}案例”,
风格:{
颜色:Highcharts.getOptions().color[0]
}
},
allowDecimals:false,
反面:错
},{//
网格线宽:0,
标题:{
文本:“平均响应时间”,
风格:{
颜色:Highcharts.getOptions().colors[3]
}
},
标签:{
格式化程序:函数(){
//获取时间戳
var时间=该值;
返回格式日期(时间,0,1);
//现在,在使用数据函数时操纵时间戳
},
风格:{
颜色:Highcharts.getOptions().colors[3]
}
},
键入:“日期时间”,
dateTimeLabelFormats:{//强制所有格式为小时:分钟:秒
第二个:“%H:%M:%S”,
分钟:“%H:%M:%S”,
小时数:“%H:%M:%S”,
日期:“%H:%M:%S”,
周:“%H:%M:%S”,
月份:“%H:%M:%S”,
年份:'%H:%M:%S'
},
}],
工具提示:{
格式化程序:函数(){
var points=这个点;
var groupingFormat=points[0]。series.options.dataGrouping.dateTimeLabelFormats[points[0]。series.currentDataGrouping.unitName][0];
var HeadePerformat=''+Highcharts.dateFormat(groupingFormat,this.x)+'
;
var pointFormat='',
本年度;
var isAllPointsHaveData=[];
点。forEach(函数(点){
如果(点y>0){
isAllPointsWaveData.push(1);
}
});
点。forEach(函数(点){
变量名称=point.series.name,
部分
var最终价值=点y;
var showntooltip=true;
如果(名称=='本年度'){
currentYear=部分=新日期(第x点)。getFullYear();
}else if(名称==‘上一年’){
part=新日期(point.x).getFullYear()-1
}else if(名称===‘平均响应时间’){
最终值=\格式\日期(点y,0,1,1);
部分=(当前年份的类型!='undefined'?name+'('+currentYear+'):name);
}否则{
最终值=\格式\日期(点y,1,1,1);
part=(当前年份的类型!==“未定义”?名称+