Javascript HighCharts:仅当系列重叠时使用共享工具提示

Javascript HighCharts:仅当系列重叠时使用共享工具提示,javascript,highcharts,highstock,Javascript,Highcharts,Highstock,在下面的HighCharts示例中,序列A和B具有相同的数据。只有B的线在图表打印区域中可见,因为它直接打印在A上 最终用户不可能知道A在B后面 我们可以在配置对象中设置tooltip.shared=true,以显示悬停在任何序列上时给定x轴点的所有数据值。然而,在我的实际例子中,我在图表上绘制了多达50个系列,这是不合适的 是否可以保持tooltip.shared=false的行为,但当用户将鼠标悬停在与一个或多个系列在该点重叠的系列上时,是否可以在工具提示中显示所有(且仅显示)重叠的系列值?

在下面的
HighCharts
示例中,序列
A
B
具有相同的数据。只有
B
的线在图表打印区域中可见,因为它直接打印在
A

最终用户不可能知道
A
B
后面

我们可以在配置对象中设置
tooltip.shared=true
,以显示悬停在任何序列上时给定x轴点的所有数据值。然而,在我的实际例子中,我在图表上绘制了多达50个系列,这是不合适的

是否可以保持
tooltip.shared=false
的行为,但当用户将鼠标悬停在与一个或多个系列在该点重叠的系列上时,是否可以在工具提示中显示所有(且仅显示)重叠的系列值?或者是否有其他用户友好的方式来表示在给定的x值处有2+个相同的y值


除非精心策划,否则highcharts还不支持这一点。请参阅这篇文章(其中有一位自称是海图工程师的用户的评论):


我想你只能依靠用户使用图例来取消选择阻止另一个序列的序列。

作为用户,如果在图表上看到50个序列,我会感到困惑-这可读吗?好主意是使用单独的yAxis或单独的窗格,但仍然是50系列


但是,您可以做一些变通。不要使用共享工具提示,但在工具提示格式化程序中,获取实际的x索引(例如
var xIndex=series.xData.indexOf(this.x);
),然后遍历所有系列,从系列数据中获取值(例如
var yValue=series.yData[xIndex];
)。现在与
this.y
进行比较,如果值相似,则在返回的工具提示中添加更多点。

Highcharts还没有解决方案。他们有一个功能,隐藏一个系列,使其他可见,这是一个很好的选择。但是,如果您需要在两个系列重叠时获得共享工具提示,可以按下图所示进行

$(function () {
    var series1 = [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4];

    var series2 = [24.9, 50.5, 106.4, 90.2, 80.0, 150.0, 160.6, 170.5, 160.4, 180.1, 95.6, 54.4];

    $('#container').highcharts({
        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },
        tooltip: {
            formatter: function () {
                var s1 = this.series.chart.series[0].processedYData[this.point.index];
                var s2 = this.series.chart.series[1].processedYData[this.point.index];
                if (s1 == s2) {
                    return '<b>' + this.series.chart.series[0].name + ' :' + s1 + '</b><br/><b>' + this.series.chart.series[1].name + ' :' + s2 + '</b><br/>in month : ' + this.x;
                }
                return '<b>' + this.series.name + ' :' + this.y + '</b><br/>in month : ' + this.x;
            }
        },
        series: [{
            data: series1
        }, {
            data: series2
        }]
    });
});
$(函数(){
var系列1=[29.9,71.5,106.4,129.2,144.0,176.0,135.6,148.5,216.4,194.1,95.6,54.4];
var序列2=[24.9,50.5,106.4,90.2,80.0,150.0,160.6,170.5,160.4,180.1,95.6,54.4];
$(“#容器”)。高图({
xAxis:{
类别:[一月、二月、三月、四月、五月、六月、七月、八月、九月、十月、十一月、十二月]
},
工具提示:{
格式化程序:函数(){
var s1=this.series.chart.series[0]。processedYData[this.point.index];
var s2=this.series.chart.series[1]。processedYData[this.point.index];
如果(s1==s2){
返回“+”this.series.chart.series[0]。name+”:“+s1+”
“+this.series.chart.series[1]。name+”:“+s2+”
在月份:“+this.x; } 返回“+this.series.name+”:“+this.y+”
月份:“+this.x; } }, 系列:[{ 数据:系列1 }, { 数据:系列2 }] }); });


参考资料:

谢谢您提供的信息。由于我显示的系列数量太多,依赖用户使用图例也不理想。我不得不禁用用户隐藏/显示legend系列的功能,因为它在大量系列中存在严重的性能问题。我希望能偶然发现“一个精心制作的作品”@PawełFus哈哈,我本以为我投票给了你对原始帖子的评论,但我不得不这么做。我会尝试实现这个解决方案,如果我能实现,我会发布一个JSFIDLE更新,并将你的答案标记为正确。关于你对“单独的yAxis或单独的平面”的评论,你能发布一个工作的JSFIDLE示例吗?该图表看起来令人困惑,然而,如果用户仅识别y值方面的前几个系列,则这些图表的主要用例是。在我们的系统中,这些是“问题系列”。然后他们将鼠标悬停在该行上,查看它是什么系列,然后单击该行向下钻取相关数据。我的意思是这样的:我尝试过使用这种解决方案,但没有效果。看起来,除非共享工具提示,否则无法从格式化程序内部访问其他值点。也许你可以调用一个外部函数来帮助解决这个问题?我在@Sualkcin comment中为此苦苦挣扎。还有别的办法吗?很好!下面是一个动态图表大小的更新示例,它以像素为单位测量距离:Malinga,感谢您在这方面的输入。我把正确答案改成了你的。我也喜欢@Sphinxxx输入,也许你可以更新答案,以显示his作为替代方法。建议将此作为highcharts的一项功能。请在这里投票:
$(function () {
    var series1 = [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4];

    var series2 = [24.9, 50.5, 106.4, 90.2, 80.0, 150.0, 160.6, 170.5, 160.4, 180.1, 95.6, 54.4];

    $('#container').highcharts({
        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },
        tooltip: {
            formatter: function () {
                var s1 = this.series.chart.series[0].processedYData[this.point.index];
                var s2 = this.series.chart.series[1].processedYData[this.point.index];
                if (s1 == s2) {
                    return '<b>' + this.series.chart.series[0].name + ' :' + s1 + '</b><br/><b>' + this.series.chart.series[1].name + ' :' + s2 + '</b><br/>in month : ' + this.x;
                }
                return '<b>' + this.series.name + ' :' + this.y + '</b><br/>in month : ' + this.x;
            }
        },
        series: [{
            data: series1
        }, {
            data: series2
        }]
    });
});