【问题标题】:Link multiple chart controls in HighCharts在 HighCharts 中链接多个图表控件
【发布时间】:2013-02-20 15:41:33
【问题描述】:

在我的网页上,我显示了 5 个带有可缩放 X 轴的不同折线图。每个图表还有许多系列,所有图表都相同。

我正在寻找控件,无论我更改哪个图表控件,您都可以在其中显示/隐藏在每个图表中发生的系列和缩放功能。

这是 Highcharts 支持的吗?

【问题讨论】:

    标签: javascript highcharts


    【解决方案1】:

    请熟悉同步三个图表并具有取消缩放按钮的示例。

    $(function() {
    var chart1;
        var chart2;
        var chart3;
        var controllingChart;
    
        var defaultTickInterval = 5;
        var currentTickInterval = defaultTickInterval;
    
        $(document).ready(function() {
            function unzoom() {
                 chart1.options.chart.isZoomed = false;
                 chart2.options.chart.isZoomed = false;
                 chart3.options.chart.isZoomed = false;
    
                chart1.xAxis[0].setExtremes(null, null);
                chart2.xAxis[0].setExtremes(null, null);
                chart3.xAxis[0].setExtremes(null, null);
            }
    
            //catch mousemove event and have all 3 charts' crosshairs move along indicated values on x axis
    
            function syncronizeCrossHairs(chart) {
                var container = $(chart.container),
                    offset = container.offset(),
                    x, y, isInside, report;
    
                container.mousemove(function(evt) {
    
                    x = evt.clientX - chart.plotLeft - offset.left;
                    y = evt.clientY - chart.plotTop - offset.top;
                    var xAxis = chart.xAxis[0];
                    //remove old plot line and draw new plot line (crosshair) for this chart
                    var xAxis1 = chart1.xAxis[0];
                    xAxis1.removePlotLine("myPlotLineId");
                    xAxis1.addPlotLine({
                        value: chart.xAxis[0].translate(x, true),
                        width: 1,
                        color: 'red',
                        //dashStyle: 'dash',                   
                        id: "myPlotLineId"
                    });
                    //remove old crosshair and draw new crosshair on chart2
                    var xAxis2 = chart2.xAxis[0];
                    xAxis2.removePlotLine("myPlotLineId");
                    xAxis2.addPlotLine({
                        value: chart.xAxis[0].translate(x, true),
                        width: 1,
                        color: 'red',
                        //dashStyle: 'dash',                   
                        id: "myPlotLineId"
                    });
    
                    var xAxis3 = chart3.xAxis[0];
                    xAxis3.removePlotLine("myPlotLineId");
                    xAxis3.addPlotLine({
                        value: chart.xAxis[0].translate(x, true),
                        width: 1,
                        color: 'red',
                        //dashStyle: 'dash',                   
                        id: "myPlotLineId"
                    });
    
                    //if you have other charts that need to be syncronized - update their crosshair (plot line) in the same way in this function.                   
                });
            }
    
             //compute a reasonable tick interval given the zoom range -
        //have to compute this since we set the tickIntervals in order
        //to get predictable synchronization between 3 charts with
        //different data.
        function computeTickInterval(xMin, xMax) {
            var zoomRange = xMax - xMin;
    
            if (zoomRange <= 2)
                currentTickInterval = 0.5;
            if (zoomRange < 20)
                currentTickInterval = 1;
            else if (zoomRange < 100)
                currentTickInterval = 5;
        }
    
        //explicitly set the tickInterval for the 3 charts - based on
        //selected range
        function setTickInterval(event) {
            var xMin = event.xAxis[0].min;
            var xMax = event.xAxis[0].max;
            computeTickInterval(xMin, xMax);
    
            chart1.xAxis[0].options.tickInterval = currentTickInterval;
            chart1.xAxis[0].isDirty = true;
            chart2.xAxis[0].options.tickInterval = currentTickInterval;
            chart2.xAxis[0].isDirty = true;
            chart3.xAxis[0].options.tickInterval = currentTickInterval;
            chart3.xAxis[0].isDirty = true;
        }
    
        //reset the extremes and the tickInterval to default values
        function unzoom() {
            chart1.xAxis[0].options.tickInterval = defaultTickInterval;
            chart1.xAxis[0].isDirty = true;
            chart2.xAxis[0].options.tickInterval = defaultTickInterval;
            chart2.xAxis[0].isDirty = true;
            chart3.xAxis[0].options.tickInterval = defaultTickInterval;
            chart3.xAxis[0].isDirty = true;
    
            chart1.xAxis[0].setExtremes(null, null);
            chart2.xAxis[0].setExtremes(null, null);
            chart3.xAxis[0].setExtremes(null, null);
        }
    
                $(document).ready(function() {
    
    
                    $('#btn').click(function(){
                        unzoom();
                    });
    
                    var myPlotLineId = "myPlotLine";
                    chart1 = new Highcharts.Chart({
                        chart: {
                            renderTo: 'container',
                            type: 'line',
                            zoomType: 'x',
                            //x axis only
                            borderColor: '#003399',
                            //'#022455',
                            borderWidth: 1,
                            isZoomed:false
                        },
                        title: {
                            text: 'Height Versus Weight'
                        },
                        subtitle: {
                            text: 'Source: Notional Test Data'
                        },
                        xAxis: {
                            title: {
                                enabled: true,
                                text: 'Height (cm)'
                            },
                            tickInterval:5,
                            startOnTick: true,
                            endOnTick: true,
                            showLastLabel: true,
                            events:{
    
                                afterSetExtremes:function(){
    
                                     if (!this.chart.options.chart.isZoomed)
                                     {                                         
                                        var xMin = this.chart.xAxis[0].min;
                                        var xMax = this.chart.xAxis[0].max;
    
                                        var zmRange = computeTickInterval(xMin, xMax);
                                        chart1.xAxis[0].options.tickInterval =zmRange;
                                        chart1.xAxis[0].isDirty = true;
                                        chart2.xAxis[0].options.tickInterval = zmRange;
                                        chart2.xAxis[0].isDirty = true;
                                        chart3.xAxis[0].options.tickInterval = zmRange;
                                        chart3.xAxis[0].isDirty = true;
    
                                       chart2.options.chart.isZoomed = true;
                                       chart3.options.chart.isZoomed = true;
                                       chart2.xAxis[0].setExtremes(xMin, xMax, true);
    
                                        chart3.xAxis[0].setExtremes(xMin, xMax, true);
                                          chart2.options.chart.isZoomed = false;
                                       chart3.options.chart.isZoomed = false;
                                    }
                                }
    
    
                            }
                        },
                        yAxis: {
                            title: {
                                text: 'Weight (kg)'
                            }
                        },
                        tooltip: {
                            formatter: function() {
                                return '' + this.x + ' km, ' + this.y + ' km';
                            }
                        },
                        legend: {
                            layout: 'vertical',
                            align: 'left',
                            verticalAlign: 'top',
                            x: 100,
                            y: 70,
                            floating: true,
                            backgroundColor: '#FFFFFF',
                            borderWidth: 1
                        },
                        plotOptions: {
                            scatter: {
                                marker: {
                                    radius: 5,
                                    states: {
                                        hover: {
                                            enabled: true,
                                            lineColor: 'rgb(100,100,100)'
                                        }
                                    }
                                },
                                states: {
                                    hover: {
                                        marker: {
                                            enabled: false
                                        }
                                    }
                                }
                            }
                        },
                        series: [{
                            name: 'Group 1',
                            color: 'rgba(223, 83, 83, .5)',
                            data: [[146.2, 51.6], [147.5, 59.0], [148.5, 49.2], [151.0, 63.0], [155.8, 53.6],
                                                                                    [157.0, 59.0], [159.1, 47.6], [161.0, 69.8], [166.2, 66.8], [168.2, 75.2],
                                                                                    [172.5, 55.2], [174.9, 54.2], [176.9, 62.5], [180.4, 42.0], [190.0, 50.0]]
    
                            },
                        {
                            name: 'dummy_data',
                            //put this in so that x axis is consistent between 3 charts to begin with
                            color: 'rgba(119, 152, 191, .5)',
                            showInLegend: false,
                            data: [[145.0, 0.0], [200.0, 0.0]]}]
    
                    }, function(chart) { //add this function to the chart definition to get synchronized crosshairs
                        syncronizeCrossHairs(chart);
                    });
    
                    chart2 = new Highcharts.Chart({
                        chart: {
                            renderTo: 'container2',
                            type: 'line',
                            zoomType: 'x',
                            //x axis only
                            borderColor: '#003399',
                            //'#022455',
                            borderWidth: 1,
                            isZoomed:false
                            /*events: {
                                selection: function(event) { //this function should zoom chart1, chart2, chart3 according to selected range
                                    controllingChart = "chart2";
                                    setTickInterval(event);
                                }
                            }*/
                        },
                        title: {
                            text: 'Height Versus Weight'
                        },
                        subtitle: {
                            text: 'Source: Notional Test Data'
                        },
                        xAxis: {
                            title: {
                                enabled: true,
                                text: 'Height (cm)'
                            },
                            tickInterval:5,
                            startOnTick: true,
                            endOnTick: true,
                            showLastLabel: true,
                            events: {
                                afterSetExtremes: function() {
                                    if (!this.chart.options.chart.isZoomed) 
                                    {
                                        var xMin = this.chart.xAxis[0].min;
                                        var xMax = this.chart.xAxis[0].max;
                                        var zmRange = computeTickInterval(xMin, xMax);
                                        chart1.xAxis[0].options.tickInterval =zmRange;
                                        chart1.xAxis[0].isDirty = true;
                                        chart2.xAxis[0].options.tickInterval = zmRange;
                                        chart2.xAxis[0].isDirty = true;
                                        chart3.xAxis[0].options.tickInterval = zmRange;
                                        chart3.xAxis[0].isDirty = true;
    
    
                                       chart1.options.chart.isZoomed = true;
                                       chart3.options.chart.isZoomed = true;
                                        chart1.xAxis[0].setExtremes(xMin, xMax, true);
    
                                        chart3.xAxis[0].setExtremes(xMin, xMax, true);
                                         chart1.options.chart.isZoomed = false;
                                       chart3.options.chart.isZoomed = false;
    
                                    }
                                }
                            }
                        },
                        yAxis: {
                            title: {
                                text: 'Weight (kg)'
                            }
                        },
                        tooltip: {
                            formatter: function() {
                                return '' + this.x + ' km, ' + this.y + ' km';
                            }
                        },
                        legend: {
                            layout: 'vertical',
                            align: 'left',
                            verticalAlign: 'top',
                            x: 100,
                            y: 70,
                            floating: true,
                            backgroundColor: '#FFFFFF',
                            borderWidth: 1
                        },
                        plotOptions: {
                            scatter: {
                                marker: {
                                    radius: 5,
                                    states: {
                                        hover: {
                                            enabled: true,
                                            lineColor: 'rgb(100,100,100)'
                                        }
                                    }
                                },
                                states: {
                                    hover: {
                                        marker: {
                                            enabled: false
                                        }
                                    }
                                }
                            }
                        },
                        series: [{
                            name: 'dummy_data',
                            color: 'rgba(223, 83, 83, .5)',
                            showInLegend: false,
                            data: [[145.0, 0.0], [200.0, 0.0]]},
                        {
                            name: 'Group 2',
                            color: 'rgba(119, 152, 191, .5)',
                            data: [[151.0, 65.6], [166.3, 71.8], [167.5, 80.7], [168.5, 72.6], [172.2, 78.8],
                                                                                                        [174.5, 74.8], [175.0, 86.4], [181.5, 78.4], [182.0, 62.0], [184.0, 81.6],
                                                                                                        [185.0, 76.6], [186.8, 83.6], [186.0, 90.0], [188.0, 74.6], [190.0, 71.0],
                                                                                                        [192.0, 79.6], [193.7, 93.8], [196.5, 70.0], [199.0, 72.4]]}]
                    }, function(chart) { //add this function to the chart definition to get synchronized crosshairs
                        //this function needs to be added to each syncronized chart 
                        syncronizeCrossHairs(chart);
    
                    });
    
                    chart3 = new Highcharts.Chart({
                        chart: {
                            renderTo: 'container3',
                            type: 'line',
                            zoomType: 'x',
                            //x axis only
                            borderColor: '#003399',
                            //'#022455',
                            borderWidth: 1,
                            isZoomed:false
                            /*events: {
                                selection: function(event) { //this function should zoom chart1, chart2, chart3
                                    controllingChart = "chart3";
                                    setTickInterval(event);
                                }
                            }*/
                        },
                        title: {
                            text: 'Height Versus Weight'
                        },
                        subtitle: {
                            text: 'Source: Notional Test Data'
                        },
                        xAxis: {
                            title: {
                                enabled: true,
                                text: 'Height (cm)'
                            },
                            tickInterval:5,
                            startOnTick: true,
                            endOnTick: true,
                            showLastLabel: true,
                            events: {
                                 afterSetExtremes: function() {
                                     if (!this.chart.options.chart.isZoomed) {
                                        var xMin = this.chart.xAxis[0].min;
                                        var xMax = this.chart.xAxis[0].max;
                                        var zmRange = computeTickInterval(xMin, xMax);
                                        chart1.xAxis[0].options.tickInterval =zmRange;
                                        chart1.xAxis[0].isDirty = true;
                                        chart2.xAxis[0].options.tickInterval = zmRange;
                                        chart2.xAxis[0].isDirty = true;
                                        chart3.xAxis[0].options.tickInterval = zmRange;
                                        chart3.xAxis[0].isDirty = true; 
    
                                       chart1.options.chart.isZoomed = true;
                                       chart2.options.chart.isZoomed = true;
                                       chart1.xAxis[0].setExtremes(xMin, xMax, true);
    
                                       chart2.xAxis[0].setExtremes(xMin, xMax, true);
                                         chart1.options.chart.isZoomed = false;
                                       chart2.options.chart.isZoomed = false;
    
                                    }
                        }
                                }
                        },
                        yAxis: {
                            title: {
                                text: 'Weight (kg)'
                            }
                        },
                        tooltip: {
                            formatter: function() {
                                return '' + this.x + ' km, ' + this.y + ' km';
                            }
                        },
                        legend: {
                            layout: 'vertical',
                            align: 'left',
                            verticalAlign: 'top',
                            x: 100,
                            y: 70,
                            floating: true,
                            backgroundColor: '#FFFFFF',
                            borderWidth: 1
                        },
                        plotOptions: {
                            scatter: {
                                marker: {
                                    radius: 5,
                                    states: {
                                        hover: {
                                            enabled: true,
                                            lineColor: 'rgb(100,100,100)'
                                        }
                                    }
                                },
                                states: {
                                    hover: {
                                        marker: {
                                            enabled: false
                                        }
                                    }
                                }
                            }
                        },
                        series: [{
                            name: 'dummy_data',
                            //I put this in to try to get the charts to have the same range on the x axis
                            color: 'rgba(223, 83, 83, .5)',
                            showInLegend: false,
                            data: [[145.0, 0.0], [200.0, 0.0]]},
                        {
                            name: 'Group 3',
                            color: 'rgba(119, 152, 191, .5)',
                            data: [[153.0, 65.6], [156.3, 71.8], [167.5, 80.7], [169.5, 72.6], [171.2, 78.8],
                                                                                                        [172.5, 74.8], [177.0, 86.4], [181.5, 78.4], [183.0, 62.0], [184.0, 81.6],
                                                                                                        [185.0, 76.6], [186.2, 83.6], [187.0, 90.0], [188.7, 74.6], [190.0, 71.0],
                                                                                                        [192.0, 79.6], [195.7, 93.8], [196.5, 70.0], [199.4, 72.4]]}]
                    }, function(chart) { //add this function to the chart definition to get synchronized crosshairs
                        //this function needs to be added to each syncronized chart 
                        syncronizeCrossHairs(chart);
    
                    });
    
    
                });
    
        });
    
    });
    

    http://jsfiddle.net/Gv7Tg/27/

    【讨论】:

    • 这非常接近我需要的谢谢!关于单击“组 1”或“组 2”按钮时如何获取事件的任何想法。一旦我发现,我可以在每个图表中按 ID 调用启用/禁用系列以链接所有按钮。
    • 这也是我一直在寻找的,但我的 xAxis 是日期时间。 computeTickInterval 和 setTickInterval 函数可以使用日期时间格式吗?我有 4 个图表要同步,但所有图表的日期都是相同的。顺便说一句,上面的 jsfiddle 做得很棒。很流畅
    • @geomajor56 当然可以,它只是 xAxis 的其他格式。所以看看 setExtremes 函数(定义正确的范围),仅此而已。
    • 你好@SebastianBochan,样品很棒..这正是我想要的。但是无论如何不要将“红线”显示为 Plot 而是使用图表的默认十字准线?谢谢
    • 不,您只能使用渲染的路径。但在我的示例中,您可以通过编辑路径添加水平线。
    【解决方案2】:

    有两种可能的解决方案:

    最简单的选择是使用额外的按钮显示/隐藏和缩放。 因此,您将在页面中添加一些按钮并执行如下功能:

    //编辑选择图表时出错:

    您应该在创建图表时创建图表并将其添加到数组中。例如:

    var charts = new Array(); 
    var chart = new Highcharts.StockChart(opts);
    charts.push(chart);
    

    那么对于函数:

    //Set xAxis extremes (zoom)
    for (var i = 0; i < charts.length; i++) {
            charts[i].xAxis[0].setExtremes(startDate, endDate);
    }
    

    更改缩放。 系列的显示和隐藏也很简单:

    Highstock Options Reference

    所以你可以调用charts[i].series[0].hide(); 来隐藏第一个系列

    另一种可能性是在用户点击图表时使用 Highcharts 事件来启动类似的功能。

    例如上图例:Highstock Options Reference

    对于缩放:

    xAxis : {
         events : {
            afterSetExtremes : afterSetExtremes
        },
    },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-16
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多