-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9dda734
commit d188a0c
Showing
16 changed files
with
692 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .generation import generate_chart_figure | ||
from .utils import return_formatted_max_y_axis_value |
138 changes: 138 additions & 0 deletions
138
metrics/domain/charts/line_single_simplified/generation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
from datetime import datetime | ||
from decimal import Decimal | ||
|
||
import plotly.graph_objects | ||
|
||
from metrics.domain.charts import chart_settings | ||
from metrics.domain.charts.colour_scheme import RGBAChartLineColours | ||
from metrics.domain.models import PlotData | ||
|
||
from .utils import return_formatted_max_y_axis_value | ||
|
||
|
||
def _build_chart_config_params( | ||
x_axis_values: list[datetime.date], | ||
y_axis_values: list[Decimal], | ||
) -> dict[str | int | Decimal]: | ||
"""Creates the parameters for `get_line_single_simplified_chart_config` | ||
Args: | ||
x_axis_values: list of dates for the x_axis of a chart | ||
y_axis_values: list of Decimal values for the y_axis of a chart | ||
Returns: | ||
dictionary of parameters for charts settings parameters | ||
""" | ||
return { | ||
"x_axis_tick_values": [x_axis_values[0], x_axis_values[-1]], | ||
"x_axis_tick_text": [ | ||
x_axis_values[0].strftime("%b, %Y"), | ||
x_axis_values[-1].strftime("%b, %Y"), | ||
], | ||
"y_axis_tick_values": [0, max(y_axis_values)], | ||
"y_axis_tick_text": [ | ||
"0", | ||
return_formatted_max_y_axis_value(y_axis_values=y_axis_values), | ||
], | ||
} | ||
|
||
|
||
def create_simplified_line_chart( | ||
*, | ||
plot_data: PlotData, | ||
chart_height: int, | ||
chart_width: int, | ||
x_axis_values: list[str], | ||
y_axis_values: list[Decimal], | ||
) -> plotly.graph_objects.Figure: | ||
"""Creates a `Figure` object for the given `values` as a line graph with a shaded region. | ||
Args: | ||
plot_data: `PlotData` model | ||
chart_height: chart width as an integer | ||
chart_width: chart height as an integer | ||
x_axis_values: list of `datetime.date` objects | ||
y_axis_values: list of `Decimal` values | ||
Returns: | ||
`Figure`: A `Plotly` object which can be | ||
written to a file, or shown. | ||
""" | ||
figure = plotly.graph_objects.Figure() | ||
|
||
selected_colour = RGBAChartLineColours.get_colour( | ||
colour=plot_data[0].parameters.line_colour | ||
) | ||
|
||
line_shape = "spline" if plot_data[0].parameters.use_smooth_lines else "linear" | ||
|
||
line_plot: dict = _create_line_plot( | ||
x_axis_values=x_axis_values, | ||
y_axis_values=y_axis_values, | ||
line_shape=line_shape, | ||
colour=selected_colour.stringified, | ||
) | ||
|
||
figure.add_trace(trace=line_plot) | ||
|
||
settings = chart_settings.ChartSettings( | ||
width=chart_width, height=chart_height, plots_data=plot_data | ||
) | ||
|
||
layout_params = _build_chart_config_params( | ||
x_axis_values=x_axis_values, | ||
y_axis_values=y_axis_values, | ||
) | ||
layout_args = settings.get_line_single_simplified_chart_config(**layout_params) | ||
figure.update_layout(**layout_args) | ||
|
||
return figure | ||
|
||
|
||
def _create_line_plot( | ||
*, | ||
x_axis_values: list[str], | ||
y_axis_values: list[str], | ||
colour: str, | ||
line_shape: str, | ||
) -> dict: | ||
return plotly.graph_objects.Scatter( | ||
x=x_axis_values, | ||
y=y_axis_values, | ||
mode="lines", | ||
line={"color": colour, "width": 3}, | ||
line_shape=line_shape, | ||
) | ||
|
||
|
||
def generate_chart_figure( | ||
*, | ||
plot_data: PlotData, | ||
chart_height: int, | ||
chart_width: int, | ||
x_axis_values: list[datetime.date], | ||
y_axis_values: list[Decimal], | ||
) -> plotly.graph_objects.Figure: | ||
"""Creates a `Figure` object for the given `chart_plots_data` as a | ||
simplified line graph with a single plot and 4 axis ticks | ||
Args: | ||
plot_data: A `PlotData` model | ||
chart_height: The chart height in pixels | ||
chart_width: The chart width in pixels | ||
x_axis_values: A list of datetime.date objects for | ||
the x-axis of a chart | ||
y_axis_values: A list of Decimal values for the | ||
y-axis of a chart | ||
Returns: | ||
`Figure`: A `Plotly` object which can then be | ||
written to a file, or shown. | ||
""" | ||
return create_simplified_line_chart( | ||
plot_data=plot_data, | ||
chart_height=chart_height, | ||
chart_width=chart_width, | ||
x_axis_values=x_axis_values, | ||
y_axis_values=y_axis_values, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from decimal import Decimal | ||
|
||
SUFFIXES = ["", "k", "m"] | ||
E_NOTATION = [1e0, 1e3, 1e6, 1e9] | ||
CONVERT_LARGE_NUMBERS_VALUE_ERROR = ( | ||
"This number is to large to be formatted for the simplified chart." | ||
) | ||
|
||
|
||
def convert_large_numbers_to_short_text(number: int) -> str: | ||
"""Converts the provided `int` into a short number string. | ||
Args: | ||
number: Integer to be formatted as a string | ||
Returns: | ||
A short number string | ||
Eg: 1000 = 1k, 2500 = 2k, 2690 = 3k, 100,000,000 = 1m | ||
""" | ||
if number >= E_NOTATION[1]: | ||
|
||
for index in range(len(E_NOTATION)): | ||
try: | ||
if E_NOTATION[index] <= number < E_NOTATION[index + 1]: | ||
return f"{str(int(number / E_NOTATION[index]))}{SUFFIXES[index]}" | ||
|
||
except IndexError: | ||
raise ValueError(CONVERT_LARGE_NUMBERS_VALUE_ERROR) | ||
|
||
return str(number) | ||
|
||
|
||
def _extract_max_value( | ||
y_axis_values: list[Decimal], | ||
) -> int: | ||
"""Extracts the highest `Decimal` value from the `y_axis_values` | ||
list and returns an `Int` rounded to the nearest large number | ||
Notes: | ||
`place_value` is the place of the first digit in the number | ||
represented by the number of digits to its right. | ||
Eg: a number of `1000` has 3 places after the first digit | ||
so `place_value` = 3 | ||
Args: | ||
y_axis_values: list of Decimal values | ||
Returns: | ||
an integer of the highest value from the list rounded to the | ||
nearest 10, 100, 1000, ... depending on the number provided. | ||
""" | ||
max_y_axis_value = round(max(y_axis_values)) | ||
place_value = len(str(max_y_axis_value)) - 1 | ||
return round(max_y_axis_value, -place_value) | ||
|
||
|
||
def return_formatted_max_y_axis_value( | ||
y_axis_values: list[Decimal], | ||
) -> str: | ||
"""Returns the highest value from `y_axis_values` as a formatted string | ||
Args: | ||
y_axis_values: A list of `Decimal` values representing | ||
the y_axis values of a `Timeseries` chart. | ||
Returns: | ||
A string of the highest value from `y_axis_values` rounded up | ||
and formatted as a short string Eg: 1400 becomes 1k | ||
""" | ||
max_value = _extract_max_value(y_axis_values=y_axis_values) | ||
return convert_large_numbers_to_short_text(number=max_value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.