diff --git a/pybadges/__init__.py b/pybadges/__init__.py index e3c6d61..6ae390c 100644 --- a/pybadges/__init__.py +++ b/pybadges/__init__.py @@ -32,7 +32,7 @@ import base64 import imghdr import mimetypes -from typing import Optional +from typing import List, Optional import urllib.parse from xml.dom import minidom @@ -43,6 +43,11 @@ from pybadges import precalculated_text_measurer from pybadges.version import __version__ +try: + from pybadges.trend import trend +except: + trend = None + _JINJA2_ENVIRONMENT = jinja2.Environment( trim_blocks=True, lstrip_blocks=True, @@ -119,13 +124,19 @@ def badge( right_link: Optional[str] = None, whole_link: Optional[str] = None, logo: Optional[str] = None, - left_color: str = '#555', + bg_color: str = '#555', + left_color: Optional[str] = None, right_color: str = '#007ec6', measurer: Optional[text_measurer.TextMeasurer] = None, embed_logo: bool = False, whole_title: Optional[str] = None, left_title: Optional[str] = None, right_title: Optional[str] = None, + right_image: Optional[str] = None, + embed_right_image: bool = False, + show_trend: Optional[List[int]] = None, + trend_color: Optional[str] = None, + trend_width: Optional[int] = 1, ) -> str: """Creates a github-style badge as an SVG image. @@ -148,16 +159,13 @@ def badge( selected. If set then left_link and right_right may not be set. logo: A url representing a logo that will be displayed inside the badge. Can be a data URL e.g. "data:image/svg+xml;utf8, {% if whole_title %} @@ -16,7 +17,7 @@ - + {% if left_title %} {{ left_title }} {% endif %} @@ -26,20 +27,26 @@ {{ right_title }} {% endif %} + {% if left_color %} + + {% endif %} {% if logo %} - + + {% endif %} + {{ left_text }} + {{ left_text }} + {% if right_image %} + {% endif %} - {{ left_text }} - {{ left_text }} {{ right_text }} {{ right_text}} {% if left_link or whole_link %} - + {% endif %} diff --git a/pybadges/trend.py b/pybadges/trend.py new file mode 100644 index 0000000..abb2a83 --- /dev/null +++ b/pybadges/trend.py @@ -0,0 +1,46 @@ +from typing import Optional, List, Tuple + +import drawSvg as draw +import numpy as np + +import pybadges + +HEIGHT = 13 +WIDTH = 107 +X_OFFSET = 7 +Y_OFFSET = 1 + + +def normalize(arr: np.ndarray) -> np.ndarray: + max_arr = np.max(arr) + if max_arr != 0: + arr /= max_arr + return arr + + +def fit_data(samples: List[int]) -> Tuple[List[int], List[int]]: + width = WIDTH - X_OFFSET + N = int(width / len(samples)) + y = np.repeat(samples, N) + xp = np.linspace(start=X_OFFSET, stop=width, num=len(y)) + yp = normalize(np.poly1d(np.polyfit(xp, y, 15))(xp)) + yp[yp > 0] *= (HEIGHT - 2) + return xp, yp + + +def trend(samples: List[int], stroke_color: str, stroke_width: int) -> str: + canvas = draw.Drawing(WIDTH, HEIGHT, origin=(0, -Y_OFFSET)) + path = draw.Path( + fill="transparent", + stroke=pybadges._NAME_TO_COLOR.get(stroke_color, stroke_color), + stroke_width=stroke_width, + stroke_linejoin="round", + ) + + xp, yp = fit_data(samples) + path.M(xp[0], yp[0]) + for x, y in zip(xp[1:], yp[1:]): + path.L(x, y) + canvas.append(path) + + return canvas.asDataUri() diff --git a/setup.py b/setup.py index 0d8160b..79dc623 100644 --- a/setup.py +++ b/setup.py @@ -69,6 +69,7 @@ def replace_relative_with_absolute(match): install_requires=['Jinja2>=2.9.0,<3', 'requests>=2.9.0,<3'], extras_require={ 'pil-measurement': ['Pillow>=5,<6'], + 'trend': ['drawsvg>=1.6.0', 'numpy>=1.19.0'], 'dev': [ 'fonttools>=3.26', 'nox', 'Pillow>=5', 'pytest>=3.6', 'xmldiff>=2.4' ], diff --git a/tests/test-badges.json b/tests/test-badges.json index f2bc92a..10bb3ae 100644 --- a/tests/test-badges.json +++ b/tests/test-badges.json @@ -29,7 +29,7 @@ "file_name": "complete.svg", "left_text": "complete", "right_text": "example", - "left_color": "green", + "bg_color": "green", "right_color": "#fb3", "left_link": "http://www.complete.com/", "right_link": "http://www.example.com", @@ -43,7 +43,7 @@ "file_name": "complete.svg", "left_text": "complete", "right_text": "example", - "left_color": "green", + "bg_color": "green", "right_color": "#fb3", "left_link": "http://www.complete.com/", "right_link": "http://www.example.com", @@ -121,7 +121,7 @@ "file_name": "tests.svg", "left_text": "tests", "right_text": "231 passed, 1 failed, 1 skipped", - "left_color": "blue", + "bg_color": "blue", "right_color": "orange" } ]