From 2aaeea8784e3644886bf8b378668c4f58b324458 Mon Sep 17 00:00:00 2001 From: Tammo Jan Dijkema Date: Sat, 3 Oct 2020 14:18:42 +0200 Subject: [PATCH] Add fanchart option with overhang A fanchart consisting of half a circle fills paper with aspect ratio 1:2. Common paper and screens have larger aspect ratios (e.g. 16:9 or 1:1.41). By adding an overhang to the fanchart, more space can be used. --- gramps/plugins/drawreport/fanchart.py | 48 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/gramps/plugins/drawreport/fanchart.py b/gramps/plugins/drawreport/fanchart.py index 25c7c02df..445f19f04 100644 --- a/gramps/plugins/drawreport/fanchart.py +++ b/gramps/plugins/drawreport/fanchart.py @@ -30,7 +30,7 @@ # python modules # #------------------------------------------------------------------------ -from math import pi, cos, sin, log10, acos +from math import pi, cos, sin, log10, acos, asin, degrees, radians def log2(val): """ @@ -69,6 +69,7 @@ from gramps.gen.display.name import displayer as _nd FULL_CIRCLE = 0 HALF_CIRCLE = 1 QUAR_CIRCLE = 2 +OVERHANG = 3 BACKGROUND_WHITE = 0 BACKGROUND_GEN = 1 @@ -96,10 +97,9 @@ def draw_wedge(doc, style, centerx, centery, radius, start_angle, path = [] - degreestoradians = pi / 180.0 - radiansdelta = degreestoradians / 2 - sangle = start_angle * degreestoradians - eangle = end_angle * degreestoradians + radiansdelta = radians(0.5) + sangle = radians(start_angle) + eangle = radians(end_angle) while eangle < sangle: eangle = eangle + 2 * pi angle = sangle @@ -162,7 +162,8 @@ class FanChart(Report): that come in the options class. maxgen - Maximum number of generations to include. - circle - Draw a full circle, half circle, or quarter circle. + circle - Draw a full circle, half circle, half circle with + overhang or quarter circle. background - Background color is generation dependent or white. radial - Print radial texts roundabout or as upright as possible. draw_empty - draw background when there is no information @@ -244,6 +245,23 @@ class FanChart(Report): _y_ = self.doc.get_usable_height() min_xy = min(_x_, _y_) + elif self.circle == OVERHANG: + if self.doc.get_usable_height() < self.doc.get_usable_width() and \ + self.doc.get_usable_height() > self.doc.get_usable_width() / 2: + # Determine overhang angle to fill the paper + radius = self.doc.get_usable_width() / 2 + _overhang_height_ = self.doc.get_usable_height() - radius + overhang_angle = degrees(asin(_overhang_height_ / radius)) + else: + overhang_angle = 25.0 + max_angle = 180 + 2 * overhang_angle + start_angle = 180 - overhang_angle + max_circular = 3 + _x_ = (self.doc.get_usable_width()/2.0) + _overhang_height_ = sin(radians(overhang_angle)) * _x_ + _y_ = self.doc.get_usable_height() - _overhang_height_ + min_xy = min(_x_, _y_) + else: # quarter circle max_angle = 90.0 start_angle = 270 @@ -308,8 +326,13 @@ class FanChart(Report): # title mark = IndexMark(title, INDEX_TYPE_TOC, 1) - self.doc.center_text('FC-Graphic-title', title, - self.doc.get_usable_width() / 2, 0, mark) + titlex = self.doc.get_usable_width() / 2 + if self.circle == OVERHANG: + titley = self.doc.get_usable_height() - _overhang_height_ / 2 + else: + titley = 0 + self.doc.center_text('FC-Graphic-title', title, titlex, titley, mark) + # wheel for generation in range(0, min(max_circular, self.max_generations)): self.draw_circular(_x_, _y_, @@ -373,7 +396,7 @@ class FanChart(Report): if self.circle == FULL_CIRCLE: return [name, val] - elif self.circle == HALF_CIRCLE: + elif self.circle in (HALF_CIRCLE, OVERHANG): return [name, val] else: if (name != "") and (val != ""): @@ -384,7 +407,7 @@ class FanChart(Report): elif generation == 6: if self.circle == FULL_CIRCLE: return [p_pn.get_first_name(), p_pn.get_surname(), val] - elif self.circle == HALF_CIRCLE: + elif self.circle in (HALF_CIRCLE, OVERHANG): return [p_pn.get_first_name(), p_pn.get_surname(), val] else: if (p_pn.get_first_name() != "") and (p_pn.get_surname() != ""): @@ -620,7 +643,7 @@ class FanChart(Report): if circle == FULL_CIRCLE: rad1 = size * ((generation * 2) - 5) rad2 = size * ((generation * 2) - 3) - elif circle == HALF_CIRCLE: + elif circle in (HALF_CIRCLE, OVERHANG): rad1 = size * ((generation * 2) - 3) rad2 = size * ((generation * 2) - 1) else: # quarter circle @@ -698,9 +721,10 @@ class FanChartOptions(MenuReportOptions): circle = EnumeratedListOption(_('Type of graph'), HALF_CIRCLE) circle.add_item(FULL_CIRCLE, _('full circle')) circle.add_item(HALF_CIRCLE, _('half circle')) + circle.add_item(OVERHANG, _('overhang')) circle.add_item(QUAR_CIRCLE, _('quarter circle')) circle.set_help(_("The form of the graph: full circle, half circle," - " or quarter circle.")) + " half circle with overhang or quarter circle.")) menu.add_option(category_name, "circle", circle) background = EnumeratedListOption(_('Background color'), BACKGROUND_GEN)