Library globals

Source canvas . draw . scales.nas

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#
# canvas.draw library - scale module for speed tape etc.
# created 12/2018 by jsb
#
# The Scale class combines draw.marks* with text labels to create scales/gauges
# to build speed tape, compass etc.

var Scale = {

    # see also canvas.draw.marksStyle
    Style: {
        new: func() {
            var obj = {
                parents: [Scale.Style, canvas.draw.marksStyle.new()],
                orientation: "u",
                spacing: 20,            # spacing in pixel
                label_interval: 1,      # one txt every n marks
                label_distance_abs: 0,  # distance between ticks and text labels in px
                label_distance_rel: 1.1,  # distance in %mark_length
                mark_color: [255,255,255,1],
                label_color: [255,255,255,1],
                fontsize: 16,           # fontsize for labels
            };
            return obj;
        },

        # the 'draw direction' for a linear scale (up, down, left, right)
        setOrientation: func(value) {
            me.orientation = chr(string.tolower(value[0]));
            if (me.orientation == "v") me.orientation = "d";
            if (me.orientation == "h") me.orientation = "r";
            return me;
        },

        setFontSize: func(value) {
            me.fontsize = num(value) or 16;
            return me;
        },

        setSpacing: func(value) {
            me.spacing = num(value) or 10;
            return me;
        },

        # draw one text label every <value> marks
        setLabelInterval: func(value) {
            me.label_interval = num(value) or 1;
            return me;
        },

        # Distance of text label to mark in pixel (be careful when resizing).
        # See also setLabelDistanceRel()
        setLabelDistanceAbs: func(value) {
            me.label_distance_abs = num(value) or 0;
            return me;
        },

        # Distance of text label to mark in %mark_length (easy scaling).
        setLabelDistanceRel: func(value) {
            me.label_distance_rel = num(value) or 1.1;
            return me;
        },

        # get alignment of text label for linear scales based on style params
        getAlignmentString: func() {
            if (me.orientation == "d") {
                return (me.mark_offset < 0 ? "right" : "left")~"-center";
            }
            elsif (me.orientation == "u") {
                return (me.mark_offset < 0 ? "right" : "left")~"-center";
            }
            elsif (me.orientation == "r") {
                return "center-"~(me.mark_offset > 0 ? "top" : "bottom");
            }
            elsif (me.orientation == "l") {
                return "center-"~(me.mark_offset > 0 ? "top" : "bottom");
            }
            else {
                return "center-center";
            }
        },
    },
};


# draw a scale on canvas group
# start     first value of scale
# count     number of values to draw
# increment value to add (can be negative)
Scale.draw = func(cgroup, start, count, increment, style=nil) {
    if (style == nil) {
        style = me.Style.new();
    }
    var label_count = count; #math.floor(math.abs(stop - start) / increment);
    if (label_count < 2) {
        return false;
    }
    var marks = canvas.draw.marksLinear(cgroup, style.orientation, label_count * style.label_interval, style.spacing, style);
    marks.setStrokeLineWidth(style.mark_width);
    var labels = cgroup.createChild("group", "labels")
        .createChildren("text", label_count);

    var length = style.spacing * style.mark_length;
    var offset = style.mark_offset * length * style.label_distance_rel;
    offset += (offset > 0) ? style.label_distance_abs : -style.label_distance_abs;
    var alignment = style.getAlignmentString();
    forindex (i; labels) {
        var txt = sprintf("%d", start + i * increment);
        var translation = i * style.spacing * style.label_interval;
        labels[i]
            .setText(txt)
            .setAlignment(alignment)
            .setFontSize(style.fontsize)
            .setColor(style.label_color);
        if (style.orientation == "d") {
            labels[i].setTranslation(offset, translation);
        }
        elsif (style.orientation == "u") {
            labels[i].setTranslation(offset, -translation);
        }
        elsif (style.orientation == "r") {
            labels[i].setTranslation(translation, offset);
        }
        elsif (style.orientation == "l") {
            labels[i].setTranslation(-translation, offset);
        }
    }
    return cgroup;
};