extjssencha-touch-2sencha-touch-2.1

Crosszoom in a sencha chart with inner padding


I have a sencha chart with crosszooming and innerPadding like the one in the fiddle. The problem I'm experiencing is that it is not possible to pull the rectangle of the cross zoom completly down to the x-axis and to the right side of the chart. When I remove the innerPadding of the chart everything works fine.

https://fiddle.sencha.com/#fiddle/mh8

Is there a workaround for this problem?


Solution

  • I've forked your fiddle with a fix, here: https://fiddle.sencha.com/#fiddle/mih

    NOTE: You question is tagged with Touch2.1 but your fiddle is in 2.4.1

    When you define your innerPadding, the innerRegion for the chart is calculated based on your padding. Excerpt from the source of CartesianChart

    shrinkBox.left += innerPadding.left;
                shrinkBox.top += innerPadding.top;
                shrinkBox.right += innerPadding.right;
                shrinkBox.bottom += innerPadding.bottom;
    
                innerWidth = width - innerPadding.left - innerPadding.right;
                innerHeight = height - innerPadding.top - innerPadding.bottom;
    
                me.setInnerRegion([shrinkBox.left, shrinkBox.top, innerWidth, innerHeight]);
    

    Now inside the onGesture (protected function) handler of CrossZoom, it actually checks the innerRegion of your chart and if your current x or y is greater than the width or height (you get this from the innerRegion of the chart) of the chart respectively, it's reset to the width/height of the chart (width and height is ). Thus, you are limited inside the padded area.

    Is there a workaround for this problem?

    You can work around this by overriding this behavior, but it's the expected behavior as far as Sencha is concerned.

    Override onGesture function of CrossZoom so that it takes the padding offset into consideration.

    //onGesture implementation in CrossZoom

        onGesture: function (e) {
        var me = this;
        if (me.zoomAnimationInProgress) {
            return;
        }
        if (me.getLocks()[me.getGesture()] === me) {
            var chart = me.getChart(),
                surface = me.getSurface(),
                region = chart.getInnerRegion(),
                chartWidth = region[2],
                chartHeight = region[3],
                xy = chart.element.getXY(),
                x = e.pageX - xy[0] - region[0],
                y = e.pageY - xy[1] - region[1];
    
            if (x < 0) {
                x = 0;
            } else if (x > chartWidth) {
                x = chartWidth; // this is where it limits you in the x-axis
            }
            if (y < 0) {
                y = 0;
            } else if (y > chartHeight) {
                y = chartHeight; // this is where it limits you in the y-axis
            }
            me.selectionRect.setAttributes({
                width: x - me.startX,
                height: y - me.startY
            });
            if (Math.abs(me.startX - x) < 11 || Math.abs(me.startY - y) < 11) {
                me.selectionRect.setAttributes({globalAlpha: 0.5});
            } else {
                me.selectionRect.setAttributes({globalAlpha: 1});
            }
            surface.renderFrame();
            return false;
        }
    }
    

    Refer the source code for more details and understanding.

    FYI: You may again have a question that you cannot start drawing your CrossZoom overlay outside the padding region. Check onGestureStart, if you are asking that question.