Skip to content

Commit

Permalink
Merge branch 'main' into fix/mutating-chart-FIELD_DEFINITIONS
Browse files Browse the repository at this point in the history
  • Loading branch information
victorgarcia98 committed Jun 23, 2023
2 parents b8251a5 + 769bddf commit 0269f0a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
1 change: 1 addition & 0 deletions documentation/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ New features
-------------

* Allow deleting multiple sensors with a single call to ``flexmeasures delete sensor`` by passing the ``--id`` option multiple times [see `PR #734 <https://www.github.com/FlexMeasures/flexmeasures/pull/734>`_]
* Make it a lot easier to read off the color legend on the asset page, especially when showing many sensors, as they will now be ordered from top to bottom in the same order as they appear in the chart (as defined in the ``sensors_to_show`` attribute), rather than alphabetically [see `PR #742 <https://www.github.com/FlexMeasures/flexmeasures/pull/742>`_]

Bugfixes
-----------
Expand Down
21 changes: 17 additions & 4 deletions flexmeasures/data/models/charts/belief_charts.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ def chart_for_multiple_sensors(
**override_chart_specs: dict,
):
# Determine the shared data resolution
all_shown_sensors = flatten_unique(sensors_to_show)
condition = list(
sensor.event_resolution
for sensor in flatten_unique(sensors_to_show)
for sensor in all_shown_sensors
if sensor.event_resolution > timedelta(0)
)
minimum_non_zero_resolution = min(condition) if any(condition) else timedelta(0)
Expand All @@ -112,6 +113,12 @@ def chart_for_multiple_sensors(
]
}

# Set up field definition for sensor descriptions
sensor_field_definition = FIELD_DEFINITIONS["sensor_description"].copy()
sensor_field_definition["scale"] = dict(
domain=[sensor.to_dict()["description"] for sensor in all_shown_sensors]
)

sensors_specs = []
for s in sensors_to_show:
# List the sensors that go into one row
Expand Down Expand Up @@ -164,7 +171,10 @@ def chart_for_multiple_sensors(
# Draw a line for each sensor (and each source)
layers = [
create_line_layer(
row_sensors, event_start_field_definition, event_value_field_definition
row_sensors,
event_start_field_definition,
event_value_field_definition,
sensor_field_definition,
)
]

Expand All @@ -186,6 +196,7 @@ def chart_for_multiple_sensors(
row_sensors,
event_start_field_definition,
event_value_field_definition,
sensor_field_definition,
shared_tooltip,
)
)
Expand Down Expand Up @@ -269,6 +280,7 @@ def create_line_layer(
sensors: list["Sensor"], # noqa F821
event_start_field_definition: dict,
event_value_field_definition: dict,
sensor_field_definition: dict,
):
event_resolutions = list(set([sensor.event_resolution for sensor in sensors]))
assert all(res == timedelta(0) for res in event_resolutions) or all(
Expand All @@ -286,7 +298,7 @@ def create_line_layer(
"encoding": {
"x": event_start_field_definition,
"y": event_value_field_definition,
"color": FIELD_DEFINITIONS["sensor_description"],
"color": sensor_field_definition,
"strokeDash": {
"scale": {
# Distinguish forecasters and schedulers by line stroke
Expand All @@ -309,6 +321,7 @@ def create_circle_layer(
sensors: list["Sensor"], # noqa F821
event_start_field_definition: dict,
event_value_field_definition: dict,
sensor_field_definition: dict,
shared_tooltip: list,
):
params = [
Expand Down Expand Up @@ -348,7 +361,7 @@ def create_circle_layer(
"encoding": {
"x": event_start_field_definition,
"y": event_value_field_definition,
"color": FIELD_DEFINITIONS["sensor_description"],
"color": sensor_field_definition,
"size": {
"condition": {"value": "200", "test": {"or": or_conditions}},
"value": "0",
Expand Down
8 changes: 5 additions & 3 deletions flexmeasures/utils/coding_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,19 @@ def sort_dict(unsorted_dict: dict) -> dict:
def flatten_unique(nested_list_of_objects: list) -> list:
"""Returns unique objects in a possibly nested (one level) list of objects.
Preserves the original order in which unique objects first occurred.
For example:
>>> flatten_unique([1, [2, 3, 4], 3, 5])
<<< [1, 2, 3, 4, 5]
>>> flatten_unique([1, [2, 20, 6], 10, [6, 2]])
<<< [1, 2, 20, 6, 10]
"""
all_objects = []
for s in nested_list_of_objects:
if isinstance(s, list):
all_objects.extend(s)
else:
all_objects.append(s)
return list(set(all_objects))
return list(dict.fromkeys(all_objects).keys())


def timeit(func):
Expand Down

0 comments on commit 0269f0a

Please sign in to comment.