1# 2# canvas.draw library - compass rose module 3# created 12/2018 by jsb 4# WARNING: this is still under development, interfaces may change 5# 6 7var CompassRose = { 8 VERSION: 1.0, 9 Style: { 10 new: func() { 11 var obj = { 12 parents: [CompassRose.Style, canvas.draw.marksStyle.new()], 13 mark_count: 36, # number of marks, count = 360 / interval 14 label_count: 12, # number of text labels (degrees) 15 label_div: 10, # >0 div. degr. by this for text labels 16 circle_color: [255,255,255,1], 17 mark_color: [255,255,255,1], 18 label_color: [255,255,255,1], 19 center_mark: 0, # draw a mark in the center of the rose 20 font: "sans", # fontsize for labels 21 font_weight: "bold", # fontsize for labels 22 fontsize: 0, # fontsize for labels 23 nesw: 1, # replace labels 0,90,180,270 by N,E,S,W 24 }; 25 obj.setMarkLength(0.1); 26 obj.setSubdivisionLength(0.5); 27 return obj; 28 }, 29 30 setMarkCount: func(value) { 31 me.mark_count = num(value) or 0; 32 return me; 33 }, 34 35 setLabelCount: func(value) { 36 me.label_count = num(value) or 0; 37 return me; 38 }, 39 40 # divide course by this value before creating text label. (try 10, 1 or 0) 41 setLabelDivisor: func(value) { 42 me.label_div = num(value) or 10; 43 return me; 44 }, 45 46 setFontSize: func(value) { 47 me.fontsize = num(value) or 26; 48 return me; 49 }, 50 }, 51}; 52 53# draw a compass rose 54# cgroup canvas group, marks and lables will be created as children 55CompassRose.draw = func(cgroup, radius, style=nil) { 56 if (style == nil) { 57 style = me.Style.new(); 58 } 59 cgroup = cgroup.createChild("group", "compass-rose"); 60 if (style.center_mark) { 61 var center = cgroup.createChild("path","center"); 62 var l = radius * 0.1; 63 center.setStrokeLineWidth(1).setColor(style.circle_color) 64 .moveTo(-l,0).line(2*l,0).moveTo(0,-l).line(0,2*l); 65 } 66 if (style.baseline_width > 0) { 67 var c = cgroup.createChild("path", "circle"); 68 c.circle(radius) 69 .setStrokeLineWidth(style.baseline_width) 70 .setColor(style.circle_color); 71 } 72 if (style.mark_count > 0) { 73 var marks = canvas.draw.marksCircular(cgroup, radius, 360 / style.mark_count, 0, 360, style); 74 marks.setStrokeLineWidth(style.mark_width); 75 } 76 var fontsize = style.fontsize; 77 if (style.fontsize == 0) { 78 fontsize = math.round(math.sqrt(radius) * 1.4); 79 } 80 if (style.label_count > 0) { 81 var labels = cgroup.createChild("group", "labels") 82 .createChildren("text", style.label_count); 83 var offset = (style.mark_offset < 0 ? -1 : 1) * style.mark_length * radius; 84 var rot = 2*math.pi/style.label_count; 85 var font = canvas.font_mapper(style.font, style.font_weight); 86 forindex (i; labels) { 87 var t = n = int(i*360 / style.label_count); 88 if (style.label_div > 0) t = int(n / style.label_div); 89 var txt = sprintf("%d", t); 90 if (style.nesw) { 91 if (n == 0) txt = "N"; 92 elsif (n == 90) txt = "E"; 93 elsif (n == 180) txt = "S"; 94 elsif (n == 270) txt = "W"; 95 } 96 labels[i] 97 .setText(txt) 98 .setFontSize(fontsize) 99 .setFont(font) 100 .setColor(style.label_color) 101 .setAlignment("center-"~(style.mark_offset < 0 ? "top" : "bottom")) 102 .setTranslation(0,-radius-offset) 103 .setCenter(0,radius+offset) 104 .setRotation(i*rot); 105 } 106 } 107 return cgroup; 108}; 109