simplecharts

SVG charts without dependencies
git clone https://git.ce9e.org/simplecharts.git

commit
ff10e7b661e16a2feaa189f40a33300a66817b48
parent
7a2066c76a7496b32d32f898edc9d73601d34535
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2019-06-04 06:09
add dots to line renderers

Diffstat

M simplecharts.py 28 ++++++++++++++++++++++++++++
M tests/no-legend_LineRenderer.svg 42 ++++++++++++++++++++++++++++++++++++++++++
M tests/no-legend_StackedAreaRenderer.svg 42 ++++++++++++++++++++++++++++++++++++++++++
M tests/simple_LineRenderer.svg 42 ++++++++++++++++++++++++++++++++++++++++++
M tests/simple_StackedAreaRenderer.svg 42 ++++++++++++++++++++++++++++++++++++++++++
M tests/single_LineRenderer.svg 14 ++++++++++++++
M tests/single_StackedAreaRenderer.svg 14 ++++++++++++++

7 files changed, 224 insertions, 0 deletions


diff --git a/simplecharts.py b/simplecharts.py

@@ -71,6 +71,12 @@ class BaseRenderer:
   71    71         return self.element(
   72    72             'rect', content, x=x, y=y, width=width, height=height, **kwargs)
   73    73 
   -1    74     def circle(self, x, y, radius=3, title=None, **kwargs):
   -1    75         content = None
   -1    76         if title:
   -1    77             content = self.element('title', escape(str(title)))
   -1    78         return self.element('circle', content, cx=x, cy=y, r=radius, **kwargs)
   -1    79 
   74    80     def path(self, points, **kwargs):
   75    81         d = 'M {},{} L'.format(*points[0])
   76    82         for x, y in points[1:]:
@@ -224,13 +230,24 @@ class LineRenderer(BaseRenderer):
  224   230         s = ''
  225   231         k = len(rows[0]['values'])
  226   232         width = self.width / len(rows)
   -1   233         dots = ''
  227   234         for j in range(k):
   -1   235             group = ''
  228   236             points = []
  229   237             for i, row in enumerate(rows):
  230   238                 x = width * (i + 0.5)
  231   239                 y = self.height * row['values'][j] / max_value
   -1   240                 group += self.circle(
   -1   241                     x,
   -1   242                     self.height - y,
   -1   243                     title=self.get_title(rows, legend, i, j),
   -1   244                 )
  232   245                 points.append((x, self.height - y))
   -1   246             dots += self.element(
   -1   247                 'g', group, fill=self.get_color(j), stroke='white'
   -1   248             )
  233   249             s += self.path(points, fill='none', stroke=self.get_color(j))
   -1   250         s += dots
  234   251         return s
  235   252 
  236   253 
@@ -242,14 +259,25 @@ class StackedAreaRenderer(BaseRenderer):
  242   259         k = len(rows[0]['values'])
  243   260         width = self.width / len(rows)
  244   261         prev = [(width * (i + 0.5), 1) for i in range(len(rows))]
   -1   262         dots = ''
  245   263         for j in range(k):
   -1   264             group = ''
  246   265             points = []
  247   266             for i, row in enumerate(rows):
  248   267                 x = width * (i + 0.5)
  249   268                 y = self.height * row['values'][j] / max_value
   -1   269                 group += self.circle(
   -1   270                     x,
   -1   271                     self.height - (prev[i][1] + y),
   -1   272                     title=self.get_title(rows, legend, i, j),
   -1   273                 )
  250   274                 points.append((x, prev[i][1] + y))
   -1   275             dots += self.element(
   -1   276                 'g', group, fill=self.get_color(j), stroke='white'
   -1   277             )
  251   278             s += self.path([
  252   279                 (x, self.height - y) for x, y in points + list(reversed(prev))
  253   280             ], fill=self.get_color(j), stroke='white')
  254   281             prev = points
   -1   282         s += dots
  255   283         return s

diff --git a/tests/no-legend_LineRenderer.svg b/tests/no-legend_LineRenderer.svg

@@ -11,4 +11,46 @@
   11    11 	<path d="M 80.0,240.0 L 240.0,160.0 400.0,160.0 560.0,80.0" fill="none" stroke="#e41a1c" />
   12    12 	<path d="M 80.0,320.0 L 240.0,320.0 400.0,240.0 560.0,400.0" fill="none" stroke="#377eb8" />
   13    13 	<path d="M 80.0,80.0 L 240.0,240.0 400.0,160.0 560.0,320.0" fill="none" stroke="#4daf4a" />
   -1    14 	<g fill="#e41a1c" stroke="white">
   -1    15 		<circle cx="80.0" cy="240.0" r="3">
   -1    16 			<title>3</title>
   -1    17 		</circle>
   -1    18 		<circle cx="240.0" cy="160.0" r="3">
   -1    19 			<title>4</title>
   -1    20 		</circle>
   -1    21 		<circle cx="400.0" cy="160.0" r="3">
   -1    22 			<title>4</title>
   -1    23 		</circle>
   -1    24 		<circle cx="560.0" cy="80.0" r="3">
   -1    25 			<title>5</title>
   -1    26 		</circle>
   -1    27 	</g>
   -1    28 	<g fill="#377eb8" stroke="white">
   -1    29 		<circle cx="80.0" cy="320.0" r="3">
   -1    30 			<title>2</title>
   -1    31 		</circle>
   -1    32 		<circle cx="240.0" cy="320.0" r="3">
   -1    33 			<title>2</title>
   -1    34 		</circle>
   -1    35 		<circle cx="400.0" cy="240.0" r="3">
   -1    36 			<title>3</title>
   -1    37 		</circle>
   -1    38 		<circle cx="560.0" cy="400.0" r="3">
   -1    39 			<title>1</title>
   -1    40 		</circle>
   -1    41 	</g>
   -1    42 	<g fill="#4daf4a" stroke="white">
   -1    43 		<circle cx="80.0" cy="80.0" r="3">
   -1    44 			<title>5</title>
   -1    45 		</circle>
   -1    46 		<circle cx="240.0" cy="240.0" r="3">
   -1    47 			<title>3</title>
   -1    48 		</circle>
   -1    49 		<circle cx="400.0" cy="160.0" r="3">
   -1    50 			<title>4</title>
   -1    51 		</circle>
   -1    52 		<circle cx="560.0" cy="320.0" r="3">
   -1    53 			<title>2</title>
   -1    54 		</circle>
   -1    55 	</g>
   14    56 </svg>

diff --git a/tests/no-legend_StackedAreaRenderer.svg b/tests/no-legend_StackedAreaRenderer.svg

@@ -11,4 +11,46 @@
   11    11 	<path d="M 80.0,407.0 L 240.0,383.0 400.0,383.0 560.0,359.0 560.0,479 400.0,479 240.0,479 80.0,479" fill="#e41a1c" stroke="white" />
   12    12 	<path d="M 80.0,359.0 L 240.0,335.0 400.0,311.0 560.0,335.0 560.0,359.0 400.0,383.0 240.0,383.0 80.0,407.0" fill="#377eb8" stroke="white" />
   13    13 	<path d="M 80.0,239.0 L 240.0,263.0 400.0,215.0 560.0,287.0 560.0,335.0 400.0,311.0 240.0,335.0 80.0,359.0" fill="#4daf4a" stroke="white" />
   -1    14 	<g fill="#e41a1c" stroke="white">
   -1    15 		<circle cx="80.0" cy="407.0" r="3">
   -1    16 			<title>3</title>
   -1    17 		</circle>
   -1    18 		<circle cx="240.0" cy="383.0" r="3">
   -1    19 			<title>4</title>
   -1    20 		</circle>
   -1    21 		<circle cx="400.0" cy="383.0" r="3">
   -1    22 			<title>4</title>
   -1    23 		</circle>
   -1    24 		<circle cx="560.0" cy="359.0" r="3">
   -1    25 			<title>5</title>
   -1    26 		</circle>
   -1    27 	</g>
   -1    28 	<g fill="#377eb8" stroke="white">
   -1    29 		<circle cx="80.0" cy="359.0" r="3">
   -1    30 			<title>2</title>
   -1    31 		</circle>
   -1    32 		<circle cx="240.0" cy="335.0" r="3">
   -1    33 			<title>2</title>
   -1    34 		</circle>
   -1    35 		<circle cx="400.0" cy="311.0" r="3">
   -1    36 			<title>3</title>
   -1    37 		</circle>
   -1    38 		<circle cx="560.0" cy="335.0" r="3">
   -1    39 			<title>1</title>
   -1    40 		</circle>
   -1    41 	</g>
   -1    42 	<g fill="#4daf4a" stroke="white">
   -1    43 		<circle cx="80.0" cy="239.0" r="3">
   -1    44 			<title>5</title>
   -1    45 		</circle>
   -1    46 		<circle cx="240.0" cy="263.0" r="3">
   -1    47 			<title>3</title>
   -1    48 		</circle>
   -1    49 		<circle cx="400.0" cy="215.0" r="3">
   -1    50 			<title>4</title>
   -1    51 		</circle>
   -1    52 		<circle cx="560.0" cy="287.0" r="3">
   -1    53 			<title>2</title>
   -1    54 		</circle>
   -1    55 	</g>
   14    56 </svg>

diff --git a/tests/simple_LineRenderer.svg b/tests/simple_LineRenderer.svg

@@ -20,4 +20,46 @@
   20    20 	<path d="M 80.0,240.0 L 240.0,160.0 400.0,160.0 560.0,80.0" fill="none" stroke="#e41a1c" />
   21    21 	<path d="M 80.0,320.0 L 240.0,320.0 400.0,240.0 560.0,400.0" fill="none" stroke="#377eb8" />
   22    22 	<path d="M 80.0,80.0 L 240.0,240.0 400.0,160.0 560.0,320.0" fill="none" stroke="#4daf4a" />
   -1    23 	<g fill="#e41a1c" stroke="white">
   -1    24 		<circle cx="80.0" cy="240.0" r="3">
   -1    25 			<title>3</title>
   -1    26 		</circle>
   -1    27 		<circle cx="240.0" cy="160.0" r="3">
   -1    28 			<title>4</title>
   -1    29 		</circle>
   -1    30 		<circle cx="400.0" cy="160.0" r="3">
   -1    31 			<title>4</title>
   -1    32 		</circle>
   -1    33 		<circle cx="560.0" cy="80.0" r="3">
   -1    34 			<title>5</title>
   -1    35 		</circle>
   -1    36 	</g>
   -1    37 	<g fill="#377eb8" stroke="white">
   -1    38 		<circle cx="80.0" cy="320.0" r="3">
   -1    39 			<title>2</title>
   -1    40 		</circle>
   -1    41 		<circle cx="240.0" cy="320.0" r="3">
   -1    42 			<title>2</title>
   -1    43 		</circle>
   -1    44 		<circle cx="400.0" cy="240.0" r="3">
   -1    45 			<title>3</title>
   -1    46 		</circle>
   -1    47 		<circle cx="560.0" cy="400.0" r="3">
   -1    48 			<title>1</title>
   -1    49 		</circle>
   -1    50 	</g>
   -1    51 	<g fill="#4daf4a" stroke="white">
   -1    52 		<circle cx="80.0" cy="80.0" r="3">
   -1    53 			<title>5</title>
   -1    54 		</circle>
   -1    55 		<circle cx="240.0" cy="240.0" r="3">
   -1    56 			<title>3</title>
   -1    57 		</circle>
   -1    58 		<circle cx="400.0" cy="160.0" r="3">
   -1    59 			<title>4</title>
   -1    60 		</circle>
   -1    61 		<circle cx="560.0" cy="320.0" r="3">
   -1    62 			<title>2</title>
   -1    63 		</circle>
   -1    64 	</g>
   23    65 </svg>

diff --git a/tests/simple_StackedAreaRenderer.svg b/tests/simple_StackedAreaRenderer.svg

@@ -20,4 +20,46 @@
   20    20 	<path d="M 80.0,407.0 L 240.0,383.0 400.0,383.0 560.0,359.0 560.0,479 400.0,479 240.0,479 80.0,479" fill="#e41a1c" stroke="white" />
   21    21 	<path d="M 80.0,359.0 L 240.0,335.0 400.0,311.0 560.0,335.0 560.0,359.0 400.0,383.0 240.0,383.0 80.0,407.0" fill="#377eb8" stroke="white" />
   22    22 	<path d="M 80.0,239.0 L 240.0,263.0 400.0,215.0 560.0,287.0 560.0,335.0 400.0,311.0 240.0,335.0 80.0,359.0" fill="#4daf4a" stroke="white" />
   -1    23 	<g fill="#e41a1c" stroke="white">
   -1    24 		<circle cx="80.0" cy="407.0" r="3">
   -1    25 			<title>3</title>
   -1    26 		</circle>
   -1    27 		<circle cx="240.0" cy="383.0" r="3">
   -1    28 			<title>4</title>
   -1    29 		</circle>
   -1    30 		<circle cx="400.0" cy="383.0" r="3">
   -1    31 			<title>4</title>
   -1    32 		</circle>
   -1    33 		<circle cx="560.0" cy="359.0" r="3">
   -1    34 			<title>5</title>
   -1    35 		</circle>
   -1    36 	</g>
   -1    37 	<g fill="#377eb8" stroke="white">
   -1    38 		<circle cx="80.0" cy="359.0" r="3">
   -1    39 			<title>2</title>
   -1    40 		</circle>
   -1    41 		<circle cx="240.0" cy="335.0" r="3">
   -1    42 			<title>2</title>
   -1    43 		</circle>
   -1    44 		<circle cx="400.0" cy="311.0" r="3">
   -1    45 			<title>3</title>
   -1    46 		</circle>
   -1    47 		<circle cx="560.0" cy="335.0" r="3">
   -1    48 			<title>1</title>
   -1    49 		</circle>
   -1    50 	</g>
   -1    51 	<g fill="#4daf4a" stroke="white">
   -1    52 		<circle cx="80.0" cy="239.0" r="3">
   -1    53 			<title>5</title>
   -1    54 		</circle>
   -1    55 		<circle cx="240.0" cy="263.0" r="3">
   -1    56 			<title>3</title>
   -1    57 		</circle>
   -1    58 		<circle cx="400.0" cy="215.0" r="3">
   -1    59 			<title>4</title>
   -1    60 		</circle>
   -1    61 		<circle cx="560.0" cy="287.0" r="3">
   -1    62 			<title>2</title>
   -1    63 		</circle>
   -1    64 	</g>
   23    65 </svg>

diff --git a/tests/single_LineRenderer.svg b/tests/single_LineRenderer.svg

@@ -9,4 +9,18 @@
    9     9 	<text dominant-baseline="middle" fill="#333" text-anchor="middle" x="400.0" y="490.0">Pears</text>
   10    10 	<text dominant-baseline="middle" fill="#333" text-anchor="middle" x="560.0" y="490.0">Bananas</text>
   11    11 	<path d="M 80.0,240.0 L 240.0,160.0 400.0,160.0 560.0,80.0" fill="none" stroke="#e41a1c" />
   -1    12 	<g fill="#e41a1c" stroke="white">
   -1    13 		<circle cx="80.0" cy="240.0" r="3">
   -1    14 			<title>3</title>
   -1    15 		</circle>
   -1    16 		<circle cx="240.0" cy="160.0" r="3">
   -1    17 			<title>4</title>
   -1    18 		</circle>
   -1    19 		<circle cx="400.0" cy="160.0" r="3">
   -1    20 			<title>4</title>
   -1    21 		</circle>
   -1    22 		<circle cx="560.0" cy="80.0" r="3">
   -1    23 			<title>5</title>
   -1    24 		</circle>
   -1    25 	</g>
   12    26 </svg>

diff --git a/tests/single_StackedAreaRenderer.svg b/tests/single_StackedAreaRenderer.svg

@@ -9,4 +9,18 @@
    9     9 	<text dominant-baseline="middle" fill="#333" text-anchor="middle" x="400.0" y="490.0">Pears</text>
   10    10 	<text dominant-baseline="middle" fill="#333" text-anchor="middle" x="560.0" y="490.0">Bananas</text>
   11    11 	<path d="M 80.0,239.0 L 240.0,159.0 400.0,159.0 560.0,79.0 560.0,479 400.0,479 240.0,479 80.0,479" fill="#e41a1c" stroke="white" />
   -1    12 	<g fill="#e41a1c" stroke="white">
   -1    13 		<circle cx="80.0" cy="239.0" r="3">
   -1    14 			<title>3</title>
   -1    15 		</circle>
   -1    16 		<circle cx="240.0" cy="159.0" r="3">
   -1    17 			<title>4</title>
   -1    18 		</circle>
   -1    19 		<circle cx="400.0" cy="159.0" r="3">
   -1    20 			<title>4</title>
   -1    21 		</circle>
   -1    22 		<circle cx="560.0" cy="79.0" r="3">
   -1    23 			<title>5</title>
   -1    24 		</circle>
   -1    25 	</g>
   12    26 </svg>