Skip to content

Commit

Permalink
DATASHADES-324 / write some tests, refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
mutantsan committed May 9, 2024
1 parent 51af8ae commit c469671
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 268 deletions.
153 changes: 10 additions & 143 deletions ckanext/charts/chart_builders/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ def __init__(
self.df = dataframe
self.settings = settings

# def columns(self) -> list[str]:
# return self.df.columns.tolist()
if self.settings.pop("sort_x", False):
self.df.sort_values(by=self.settings["x"], inplace=True)

if self.settings.pop("sort_y", False):
self.df.sort_values(by=self.settings["y"], inplace=True)

if limit := self.settings.pop("limit", 0):
self.df = self.df.head(int(limit))

self.settings.pop("query", None)

@classmethod
@abstractmethod
Expand Down Expand Up @@ -47,147 +55,6 @@ def to_html(self) -> str:
def to_json(self) -> str:
pass

# def set_type(self, chart_type: str) -> Self:
# self.type = chart_type

# return self

# def set_x_axis(self, x: str) -> Self:
# if not x:
# self.x = ""
# return self

# if not isinstance(x, str):
# raise ValueError("X axis must be a string")

# if x not in self.columns():
# raise ValueError(f"Column {x} does not exist in the dataframe")

# self.x = x

# return self

# def set_y_axis(self, y: str) -> Self:
# if not y:
# self.y = ""
# return self

# if not isinstance(y, str):
# raise ValueError("Y axis must be a string")

# if y not in self.columns():
# raise ValueError(f"Column {y} does not exist in the dataframe")

# self.y = y

# return self

# def set_x_label(self, x_label: str) -> Self:
# if not x_label:
# self.x_label = ""
# return self

# if not isinstance(x_label, str):
# raise ValueError("X label must be a string")

# self.x_label = x_label

# return self

# def set_y_label(self, y_label: str) -> Self:
# if not y_label:
# self.y_label = ""
# return self

# if not isinstance(y_label, str):
# raise ValueError("Y label must be a string")

# self.y_label = y_label

# return self

# def set_title(self, title: str) -> Self:
# if not title:
# self.title = ""
# return self

# if not isinstance(title, str):
# raise ValueError("Title must be a string")

# self.title = title

# return self

# def set_log_x(self, log_x: bool) -> Self:
# if not isinstance(log_x, bool):
# raise ValueError("log_x must be a boolean")

# self.log_x = log_x

# return self

# def set_query(self, query: str) -> None:

# self.df.query(query, inplace=True)

# def set_log_y(self, log_y: bool) -> Self:
# if not isinstance(log_y, bool):
# raise ValueError("log_y must be a boolean")

# self.log_y = log_y

# return self

# def sort_by_x(self) -> Self:
# self.df.sort_values(by=self.x, inplace=True)

# return self

# def sort_by_y(self) -> Self:
# self.df.sort_values(by=self.y, inplace=True)

# return self

# def set_color(self, color: str | None) -> Self:
# if not color:
# self.color = ""
# return self

# if not isinstance(color, str):
# raise ValueError("Color must be a string")

# if color not in self.columns():
# raise ValueError(f"Column {color} does not exist in the dataframe")

# self.color = color

# return self

# def set_opacity(self, opacity: float) -> Self:
# if opacity < 0 or opacity > 1:
# raise ValueError("Opacity must be between 0 and 1")

# self.opacity = opacity

# return self

# def set_animation_frame(self, animation_frame: str) -> Self:
# if not animation_frame:
# self.animation_frame = ""
# return self

# if not isinstance(animation_frame, str):
# raise ValueError("Animation frame must be a string")

# if animation_frame not in self.columns():
# raise ValueError(
# f"Column {animation_frame} does not exist in the dataframe"
# )

# self.animation_frame = animation_frame

# return self

def drop_empty_values(self, data: dict[str, Any]) -> dict[str, Any]:
"""Remove empty values from the dictionary"""
result = {}
Expand Down
28 changes: 15 additions & 13 deletions ckanext/charts/chart_builders/plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ def __init__(self, df: pd.DataFrame, settings: dict[str, Any]) -> None:

self.settings = self.drop_view_fields(self.drop_empty_values(self.settings))

if self.settings.pop("sort_x", False):
self.df.sort_values(by=self.settings["x"], inplace=True)

if self.settings.pop("sort_y", False):
self.df.sort_values(by=self.settings["y"], inplace=True)

if limit := self.settings.pop("limit", 0):
self.df = self.df.head(int(limit))

self.settings.pop("query", None)

def drop_view_fields(self, settings: dict[str, Any]) -> dict[str, Any]:
view_fields = ["title", "notes", "engine", "type"]

Expand Down Expand Up @@ -91,6 +80,11 @@ def to_html(self) -> str:


class BasePlotlyForm(ABC):
"""
TODO: move some of the common methods to the BaseChartForm class, that
will be used by all chart form builders.
"""

def __init__(self, resource_id: str) -> None:
try:
self.df = fetchers.DatastoreDataFetcher(resource_id).fetch_data()
Expand All @@ -104,10 +98,16 @@ def get_validator(self, name: str) -> types.ValueValidator:

@abstractmethod
def get_form_fields(self) -> list[dict[str, Any]]:
pass
"""The list for a specific chart could be defined similar to a scheming
dataset schema fields."""

def get_expanded_form_fields(self):
return self.expand_schema_fields(self.drop_validators(self.get_form_fields()))
"""Expands the presets."""
return self.expand_schema_fields(
self.drop_validators(
self.get_form_fields(),
),
)

def expand_schema_fields(
self,
Expand Down Expand Up @@ -334,6 +334,8 @@ def limit_field(self) -> dict[str, Any]:
return {
"field_name": "limit",
"label": "Limit",
"form_snippet": "chart_text.html",
"input_type": "number",
"validators": [
self.get_validator("default")(100),
self.get_validator("int_validator"),
Expand Down
7 changes: 0 additions & 7 deletions ckanext/charts/config_declaration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,3 @@ groups:
editable: true
type: bool
validators: ignore_empty boolean_validator

- key: ckanext.charts.use_serverside_rendering
description: Use server-side rendering if possible
default: false
editable: true
type: bool
validators: ignore_empty boolean_validator
11 changes: 0 additions & 11 deletions ckanext/charts/config_schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,3 @@ fields:
label: True
- value: false
label: False

- field_name: ckanext.charts.use_serverside_rendering
label: Use Server-side Rendering
help_text: Use server-side rendering if possible.
preset: select
required: true
choices:
- value: true
label: True
- value: false
label: False
2 changes: 1 addition & 1 deletion ckanext/charts/logic/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def float_validator(value):


def validate_chart_extras(key, data, errors, context):
settings = data[("__extras",)]
settings = data.get(("__extras",), {})

if "engine" not in settings:
settings, _ = tk.navl_validate(settings, default_schema(), {})
Expand Down
32 changes: 0 additions & 32 deletions ckanext/charts/templates/charts/__chartjs.html

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
{% endfor %}
</ul>
{#}

{#}
<button class="btn btn-default" id="chart-clear" type="button" style="position: absolute; right: 0; top: 0;">{{ _("Clear") }}</button>
{#}
Expand Down
19 changes: 19 additions & 0 deletions ckanext/charts/templates/scheming/form_snippets/chart_text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{#} alterations: type=field.input_type {#}

{% import 'macros/form.html' as form %}

{% call form.input(
field.field_name,
id='field-' + field.field_name,
label=h.scheming_language_text(field.label),
placeholder=h.scheming_language_text(field.form_placeholder),
value=data[field.field_name],
error=errors[field.field_name],
classes=field.classes if 'classes' in field else ['control-medium'],
attrs=dict({"class": "form-control"}, **(field.get('form_attrs', {}))),
is_required=h.scheming_field_required(field),
type=field.input_type
)
%}
{%- snippet 'scheming/form_snippets/help_text.html', field=field -%}
{% endcall %}
Loading

0 comments on commit c469671

Please sign in to comment.