1

当图表呈现时,我正在做这样的事情来调整我的 plotband 的大小:

  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 轴,它们之间有一些填充,每个轴可能有它自己的 plotbands。我不希望这些溢出到其他轴,因为它们看起来像较小的单个图表。如果带内的某个点悬停在上面,我还将更改悬停格式化程序以显示这些绘图带的工具提示。

我遇到的问题是,如果单击,拖动以缩放 plotbands 会恢复到它们通过整个图表的状态。我编写了一些代码来删除它们并将它们重新添加,但似乎我需要在 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 值在重绘结束时是正确的,但是,高度仍然会渲染到图表的整个高度。

编辑:

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

4

1 回答 1

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 事件在重绘和缩放发生后触发。我认为在重绘期间写入这些值会导致它们在缩放完成时被覆盖。

希望这对其他人有帮助。

于 2013-09-14T00:16:45.463 回答