def _draw_circle_segment( self, dr: svgwrite.Drawing, tracks: List[Track], a1: float, a2: float, rr: ValueRange, center: XY, ): length = sum([t.length for t in tracks]) has_special = len([t for t in tracks if t.special]) > 0 color = self.color(self.poster.length_range_by_date, length, has_special) r1 = rr.lower() r2 = ( rr.lower() + rr.diameter() * length / self.poster.length_range_by_date.upper() ) sin_a1, cos_a1 = math.sin(a1), math.cos(a1) sin_a2, cos_a2 = math.sin(a2), math.cos(a2) path = dr.path( d=("M", center.x + r1 * sin_a1, center.y - r1 * cos_a1), fill=color, stroke="none", ) path.push("l", (r2 - r1) * sin_a1, (r1 - r2) * cos_a1) path.push(f"a{r2},{r2} 0 0,0 {r2 * (sin_a2 - sin_a1)},{r2 * (cos_a1 - cos_a2)}") path.push("l", (r1 - r2) * sin_a2, (r2 - r1) * cos_a2) dr.add(path)
def _draw_circle_segment( self, dr: svgwrite.Drawing, g: svgwrite.container.Group, tracks: typing.List[Track], a1: float, a2: float, rr: ValueRange, center: XY, ) -> None: length = sum([t.length() for t in tracks]) has_special = len([t for t in tracks if t.special]) > 0 color = self.color(self.poster.length_range_by_date, length, has_special) max_length = self.poster.length_range_by_date.upper() assert max_length is not None r1 = rr.lower() assert r1 is not None r2 = rr.interpolate((length / max_length).magnitude) sin_a1, cos_a1 = math.sin(a1), math.cos(a1) sin_a2, cos_a2 = math.sin(a2), math.cos(a2) path = dr.path( d=("M", center.x + r1 * sin_a1, center.y - r1 * cos_a1), fill=color, stroke="none", ) path.push("l", (r2 - r1) * sin_a1, (r1 - r2) * cos_a1) path.push( f"a{r2},{r2} 0 0,0 {r2 * (sin_a2 - sin_a1)},{r2 * (cos_a1 - cos_a2)}" ) path.push("l", (r1 - r2) * sin_a2, (r2 - r1) * cos_a2) date_title = str(tracks[0].start_time().date()) str_length = utils.format_float(self.poster.m2u(length)) path.set_desc(title=f"{date_title} {str_length} {self.poster.u()}") g.add(path)
def __compute_track_statistics(self): length_range = ValueRange() total_length = 0 weeks = {} for t in self.tracks: total_length += t.length length_range.extend(t.length) # time.isocalendar()[1] -> week number weeks[(t.start_time.year, t.start_time.isocalendar()[1])] = 1 return ( total_length, total_length / len(self.tracks), length_range.lower(), length_range.upper(), len(weeks), )
def color(self, length_range: ValueRange, length: float, is_special: bool = False) -> str: assert length_range.is_valid() assert length_range.contains(length) color1 = (self.poster.colors["special"] if is_special else self.poster.colors["track"]) color2 = (self.poster.colors["special2"] if is_special else self.poster.colors["track2"]) diff = length_range.diameter() if diff == 0: return color1 return utils.interpolate_color(color1, color2, (length - length_range.lower()) / diff)
def _draw_rings(self, dr: svgwrite.Drawing, center: XY, radius_range: ValueRange): length_range = self.poster.length_range_by_date ring_distance = self._determine_ring_distance() if ring_distance is None: return distance = ring_distance while distance < length_range.upper(): radius = ( radius_range.lower() + radius_range.diameter() * distance / length_range.upper() ) dr.add( dr.circle( center=center.tuple(), r=radius, stroke=self._ring_color, stroke_opacity="0.2", fill="none", stroke_width=0.3, ) ) distance += ring_distance