Coverage for /builds/svesch/cikit/src/cikit/timeline/charts.py: 61%

18 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-10-09 14:17 +0000

1# SPDX-License-Identifier: GPL-3.0-or-later 

2"""Custom pygal chart implementations used by cikit timelines. 

3 

4The module contains small pygal extensions required by timeline presets. These 

5classes stay internal to the timeline package and are selected through presets. 

6 

7Author: 

8 Sven Schlender 

9Date: 

10 2026-09-13 

11""" 

12 

13import pygal 

14 

15 

16class FilledLine(pygal.Line): 

17 """Render filled line charts without stroked fill boundaries. 

18 

19 Pygal normally uses one closed path for both the filled area and its stroke. 

20 This implementation separates fill and stroke so no vertical boundary lines 

21 are drawn at the beginning and end of the series. 

22 """ 

23 

24 def line(self, serie, rescale=False): 

25 """Draw one filled line series using separate fill and stroke paths. 

26 

27 Args: 

28 serie: Pygal series to render. 

29 rescale: Whether secondary-axis values must be rescaled. 

30 """ 

31 serie_node = self.svg.serie(serie) 

32 

33 if rescale and self.secondary_series: 33 ↛ 34line 33 didn't jump to line 34 because the condition on line 33 was never true

34 points = self._rescale(serie.points) 

35 else: 

36 points = serie.points 

37 

38 if self.interpolate: 38 ↛ 39line 38 didn't jump to line 39 because the condition on line 38 was never true

39 points = serie.interpolated 

40 if rescale and self.secondary_series: 

41 points = self._rescale(points) 

42 

43 view_values = list(map(self.view, points)) 

44 

45 if not serie.stroke: 45 ↛ 46line 45 didn't jump to line 46 because the condition on line 45 was never true

46 return 

47 

48 if serie.fill: 48 ↛ 54line 48 didn't jump to line 54 because the condition on line 48 was always true

49 fill_values = self._fill(view_values) 

50 self.svg.line(serie_node["plot"], fill_values, close=True, 

51 class_="line reactive timeline-fill", 

52 style="stroke: none; pointer-events: none") 

53 

54 self.svg.line(serie_node["plot"], view_values, 

55 class_="line reactive nofill timeline-stroke")