PlotKit.Layout.prototype.hitTest = function()

in web/servicemix-web-console/src/main/webapp/js/plotkit/Layout.js [174:244]


PlotKit.Layout.prototype.hitTest = function(x, y) {
    // TODO: make this more efficient with better datastructures
    //       for this.bars, this.points and this.slices

    var f = MochiKit.Format.twoDigitFloat;

    if ((this.style == "bar") && this.bars && (this.bars.length > 0)) {
        for (var i = 0; i < this.bars.length; i++) {
            var bar = this.bars[i];
            if ((x >= bar.x) && (x <= bar.x + bar.w) 
                && (y >= bar.y) && (y - bar.y <= bar.h))
                return bar;
        }
    }

    else if (this.style == "line") {
        if (this.hitTestCache.x2maxy == null) {
            this._regenerateHitTestCache();
        }

        // 1. find the xvalues that equal or closest to the give x
        var xval = x / this.xscale;
        var xvalues = this.hitTestCache.xvalues;
        var xbefore = null;
        var xafter = null;

        for (var i = 1; i < xvalues.length; i++) {
            if (xvalues[i] > xval) {
                xbefore = xvalues[i-1];
                xafter = xvalues[i];
                break;
            }
        }

        if ((xbefore != null)) {
            var ybefore = this.hitTestCache.x2maxy[xbefore];
            var yafter = this.hitTestCache.x2maxy[xafter];
            var yval = (1.0 - y)/this.yscale;

            // interpolate whether we will fall inside or outside
            var gradient = (yafter - ybefore) / (xafter - xbefore);
            var projmaxy = ybefore + gradient * (xval - xbefore);
            if (projmaxy >= yval) {
                // inside the highest curve (roughly)
                var obj = {xval: xval, yval: yval,
                           xafter: xafter, yafter: yafter,
                           xbefore: xbefore, ybefore: ybefore,
                           yprojected: projmaxy
                };
                return obj;
            }
        }
    }

    else if (this.style == "pie") {
        var dist = Math.sqrt((y-0.5)*(y-0.5) + (x-0.5)*(x-0.5));
        if (dist > this.options.pieRadius)
            return null;

        // TODO: actually doesn't work if we don't know how the Canvas
        //       lays it out, need to fix!
        var angle = Math.atan2(y - 0.5, x - 0.5) - Math.PI/2;
        for (var i = 0; i < this.slices.length; i++) {
            var slice = this.slices[i];
            if (slice.startAngle < angle && slice.endAngle >= angle)
                return slice;
        }
    }

    return null;
};