Highcharts有没有办法在缩放后调整绘图带的大小?

时间:2013-09-13 00:20:33

标签: javascript jquery svg highcharts

当图表渲染时,我正在做类似这样的事情来调整我的绘图带:

  var _Chart = new Highcharts.Chart( options, function ( chart ) {
     for ( var i = 0; i < chart.xAxis[0].plotLinesAndBands.length; i++ ) {
         var band = chart.xAxis[0].plotLinesAndBands[i].svgElem, path = band.d.split(' ');

         var bottomString = chart.xAxis[0].plotLinesAndBands[i].options.iMBottom + '';
         var topString = chart.xAxis[0].plotLinesAndBands[i].options.iMTop + '';

         path[2] = bottomString;
         path[path.length - 1] = bottomString;

         path[5] = topString;
         path[7] = topString;

         band.attr('d', path);
      }
  });

这允许我设置图表的Y轴的顶部和底部。我们在同一个图表中显示多个Y轴,它们之间有一些填充,每个轴可能有它自己的绘图带。我不希望那些溢出到其他Axis,因为它们看起来像较小的个人图表。如果乐队中的一个点悬停在上面,我也会更改悬停格式器以显示这些绘图带的工具提示。

我遇到的问题是,如果单击,拖动以缩放绘图带会恢复到乐队遍历整个图表的状态。我写了一些代码来删除它们并将它们重新添加,但似乎我需要在addPlotBand函数上进行回调以在实际添加和渲染之前更改SVG数组。我尝试重新添加它然后尝试重新绘制它,但是没有用。

添加新的绘图带时,有没有办法调整SVG元素,以便我可以改变SVG元素?

编辑:

这里有更多信息。我尝试使用选择事件删除所有波段,然后调用重绘,它调用自定义重绘事件以返回SVG值。这是看起来的样子(选择事件是第一种粗略但它有效):

    SelectChart: function (chart) {

    var plotBandData = new Array();

    for (var i = 0; i < chart.xAxis[0].plotLinesAndBands.length; i++) {
        var band = chart.xAxis[0].plotLinesAndBands[i].svgElem, path = band.d.split(' ');

        var plotBand = chart.xAxis[0].plotLinesAndBands[i];
        //get all the plot band info so we can recreate them after resize

        var pbd = {
            from: plotBand.options.from,
            to: plotBand.options.to,
            id: plotBand.options.id,
            bottom: plotBand.options.iMBottom,
            top: plotBand.options.iMTop,
            color: plotBand.options.color
        };

        plotBandData.push(pbd);

    }

    //delete all existing plot bands:
    for (var i = 0; i < plotBandData.length; i++) {
        chart.xAxis[0].removePlotBand(plotBandData[i].id);
    }

    for (var i = 0; i < plotBandData.length; i++) {
        //Add plotband back in
        chart.xAxis[0].addPlotBand({
            from: plotBandData[i].from,
            to: plotBandData[i].to,
            color: plotBandData[i].color,
            id: plotBandData[i].id,
            iMBottom: plotBandData[i].bottom,
            iMTop: plotBandData[i].top
        });
    }

},

然后我的重绘事件看起来像这样:

    RedrawChart: function (chart){
    //SVG Code:
    for (var i = 0; i < chart.xAxis[0].plotLinesAndBands.length; i++) {
        var band = chart.xAxis[0].plotLinesAndBands[i].svgElem, path = band.d.split(' ');
        var bottomString = chart.xAxis[0].plotLinesAndBands[i].options.iMBottom + '';
        var topString = chart.xAxis[0].plotLinesAndBands[i].options.iMTop + '';

        path[2] = bottomString;
        path[path.length - 1] = bottomString;

        /*JH: this is interesting, the second value for top is typically in the 8th spot in the array
            However, before it's rendered the two right most "L"s are removed shifting everything to the left.
            an example would be:

            After render:
            M 525 100 L 525 100 L 525 50 L 707 50 L 707 100

            Before render (which is the state it's in here):
            M 525 100 L 525 100 L 525 50 707 50 707 100

            So you can see that the 8th value after render which is second top is shifted over one space.
            The last value which is the second bottom is shifted over 2 spaces.
        */
        path[5] = topString;
        path[7] = topString;

        band.attr('d', path);
    }
},

我的SVG值在重绘结束时是正确的,但是,高度仍然会渲染到图表的整个高度。

修改

现在,如果我只放大缩放拉伸中可见的绘图带到图表的整个高度。重置缩放后,所有其他绘图带的大小都是正确的。然后,如果我选择没有波段的图表区域,则单击缩小所有图表波段是正确的。似乎只与select上的可见情节带有关。

1 个答案:

答案 0 :(得分:0)

这是有效的:

我创建了一个在X轴上触发的新方法afterSetExtremes()方法(我想如果你在y轴上执行此操作,则会在那里触发它)。我基本上只是从上面两种方法中获取代码并将其全部放在那里。这是从xAxis.afterSetExtremes()事件中触发的代码:

    AfterChartSetExteremes: function (xAxis) {

    var plotBandData = new Array();

    for (var i = 0; i < xAxis.plotLinesAndBands.length; i++) {

        //get all the plot band info so we can recreate them after resize
        var plotBand = xAxis.plotLinesAndBands[i];

        var pbd = {
            from: plotBand.options.from,
            to: plotBand.options.to,
            id: plotBand.options.id,
            bottom: plotBand.options.iMBottom,
            top: plotBand.options.iMTop,
            color: plotBand.options.color
        };

        plotBandData.push(pbd);

    }

    //delete all existing plot bands:
    for (var x = 0; x < plotBandData.length; x++) {
        xAxis.removePlotBand(plotBandData[x].id);
    }

    for (var y = 0; y < plotBandData.length; y++) {
        //Add plotband back in
        xAxis.addPlotBand({
            from: plotBandData[y].from,
            to: plotBandData[y].to,
            color: plotBandData[y].color,
            id: plotBandData[y].id,
            iMBottom: plotBandData[y].bottom,
            iMTop: plotBandData[y].top
        });

    }

    $.each(xAxis.plotLinesAndBands, function (i, pband) {
        if (this.svgElem !== undefined) {
            var band = this.svgElem;
            path = band.d.split(' ');
            var bottomString = this.options.iMBottom + '';
            var topString = this.options.iMTop + '';

            path[2] = bottomString;
            path[path.length - 1] = bottomString;

            /*JH: this is interesting, the second value for top is typically in the 8th spot in the array
                However, before it's rendered the two right most "L"s are removed shifting everything to the left.
                an example would be:

                After render:
                M 525 100 L 525 100 L 525 50 L 707 50 L 707 100

                Before render (which is the state it's in here):
                M 525 100 L 525 100 L 525 50 707 50 707 100

                So you can see that the 8th value after render which is second top is shifted over one space.
                The last value which is the second bottom is shifted over 2 spaces.
            */
            path[5] = topString;
            path[7] = topString;

            this.svgElem.attr('d', path);
        }
    });

    //Need to reset formatter here?
}

来自函数的xAxis是来自afterSetExtremes事件的“this”,所以我就像这样传递它:

function() {return PureSense.Clifford.IM.Charting.AfterChartSetExteremes(this);}

有效。放大或重置缩放后,所有绘图带都会调整大小。我实际上已经通过我的初始帖子中的方法一直走过highcharts代码。我看到SVG值确实设置正确并一直保持。有些事情发生在重绘之外,我无法抓住它。

我确实知道它会发生,因为如果你查看我的评论,“d”数组是页面上SVG元素之外的两个项目(如果你使用F12开发工具查看它)。重绘后和放大后触发afterSetExtreme事件。我认为在重绘过程​​中编写这些值会导致它们在缩放结束时被覆盖。

希望这对其他人有帮助。