Graph2D_Axis.prototype.draw = function()

in lnt/server/ui/static/View2D.js [718:852]


Graph2D_Axis.prototype.draw = function(graph, ctx, ll, ur, mainUR) {
    var dir = this.dir, ndir = 1 - this.dir;
    var vMin = ll[dir];
    var vMax = ur[dir];
    var near = ll[ndir];
    var far = ur[ndir];
    var border = mainUR[ndir];

    var line_base = (graph.getPixelSize()[0] + graph.getPixelSize()[1]) * .5;
    ctx.lineWidth = 2 * line_base;
    ctx.strokeStyle = "rgb(0,0,0)";

    ctx.beginPath();
    var co = vec2_cswap([vMin, far], dir);
    co = graph.graphInfo.toNDC(co);
    ctx.moveTo(co[0], co[1]);
    var co = vec2_cswap([vMax, far], dir);
    co = graph.graphInfo.toNDC(co);
    ctx.lineTo(co[0], co[1]);
    ctx.stroke();

    var delta = vMax - vMin;
    var steps = Math.floor(Math.log(delta) / Math.log(10));
    if (delta / Math.pow(10, steps) >= 5.0) {
        var size = .5;
    } else if (delta / Math.pow(10, steps) >= 2.5) {
        var size = .25;
    } else {
        var size = .1;
    }
    size *= Math.pow(10, steps);

    if (steps <= 0) {
        var iDigits = 0, fDigits = 1 + Math.abs(steps);
    } else {
        var iDigits = steps, fDigits = 0;
    }

    var start = Math.ceil(vMin / size);
    var end = Math.ceil(vMax / size);

    // FIXME: Draw in window coordinates to make crisper.

    // FIXME: Draw grid in layers to avoid ugly overlaps.

    for (var i = start; i != end; ++i) {
        if (i == 0) {
            ctx.lineWidth = 3 * line_base;
            var p = .5;
        } else if (!(i & 1)) {
            ctx.lineWidth = 2 * line_base;
            var p = .5;
        } else {
            ctx.lineWidth = 1 * line_base;
            var p = .75;
        }

        ctx.beginPath();
        var co = vec2_cswap([i * size, lerp(near, far, p)], dir);
        co = graph.graphInfo.toNDC(co);
        ctx.moveTo(co[0], co[1]);
        var co = vec2_cswap([i * size, far], dir);
        co = graph.graphInfo.toNDC(co);
        ctx.lineTo(co[0], co[1]);
        ctx.stroke();
    }

    for (var alt = 0; alt < 2; ++alt) {
        if (alt)
            ctx.strokeStyle = "rgba(190,190,190,.5)";
        else
            ctx.strokeStyle = "rgba(128,128,128,.5)";
        ctx.lineWidth = 1 * line_base;
        ctx.beginPath();
        for (var i = start; i != end; ++i) {
            if (i == 0)
                continue;
            if ((i & 1) == alt) {
                var co = vec2_cswap([i * size, far], dir);
                co = graph.graphInfo.toNDC(co);
                ctx.moveTo(co[0], co[1]);
                var co = vec2_cswap([i * size, border], dir);
                co = graph.graphInfo.toNDC(co);
                ctx.lineTo(co[0], co[1]);
            }
        }
        ctx.stroke();

        if (start <= 0 && 0 < end) {
            ctx.beginPath();
            var co = vec2_cswap([0, far], dir);
            co = graph.graphInfo.toNDC(co);
            ctx.moveTo(co[0], co[1]);
            var co = vec2_cswap([0, border], dir);
            co = graph.graphInfo.toNDC(co);
            ctx.lineTo(co[0], co[1]);
            ctx.strokeStyle = "rgba(64,64,64,.5)";
            ctx.lineWidth = 3 * line_base;
            ctx.stroke();
        }
    }

    // FIXME: Draw this in screen coordinates, and stop being stupid. Also,
    // figure out font height?
    if (this.dir == 1) {
        var offset = [-.5, -.25];
    } else {
        var offset = [-.5, 1.1];
    }
    ctx.fillStyle = "rgb(0,0,0)";
    var pxl = graph.getPixelSize();
    for (var i = start; i != end; ++i) {
        if ((i & 1) == 0) {
            var label = this.format(i * size, iDigits, fDigits);
            ctx.save();
            var co = vec2_cswap([i*size, lerp(near, far, .5)], dir);
            co = graph.graphInfo.toNDC(co);
            ctx.translate(co[0], co[1]);
            ctx.scale(pxl[0], -pxl[1]);
            // FIXME: Abstract.
            var bb_w = label.length * 5;
            if (ctx.measureText != null)
                bb_w = ctx.measureText(label).width;
            var bb_h = 12;
            // FIXME: Abstract? Or ignore.
            if (ctx.fillText != null) {
                ctx.fillText(label, bb_w*offset[0], bb_h*offset[1]);
            } else if (ctx.mozDrawText != null) {
                ctx.translate(bb_w*offset[0], bb_h*offset[1]);
                ctx.mozDrawText(label);
            }
            ctx.restore();
        }
    }
};