From 7eceabcdb5ae7ad8d3bcec739097a2910944e9fa Mon Sep 17 00:00:00 2001 From: Felix Claessen <30658763+Flix6x@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:40:43 +0100 Subject: [PATCH] Add chart theme (#221) Let charts with sensor data be requested in one of the supported vega-lite themes (incl. a dark theme). * Add tooltip theme * Expand to cover other chart options * Use chart options in sensors UI template * Move chart options from JS to Python * Use chart options in sensors chart view * Avoid changing imported options across views * Changelog entry --- documentation/changelog.rst | 1 + flexmeasures/ui/templates/views/sensors.html | 7 +------ flexmeasures/ui/utils/chart_defaults.py | 7 +++++++ flexmeasures/ui/utils/view_utils.py | 3 +++ flexmeasures/ui/views/sensors.py | 14 +++++++++++++- 5 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 flexmeasures/ui/utils/chart_defaults.py diff --git a/documentation/changelog.rst b/documentation/changelog.rst index f15b7fdd5..46548b382 100644 --- a/documentation/changelog.rst +++ b/documentation/changelog.rst @@ -7,6 +7,7 @@ v0.8.0 | November XX, 2021 New features ----------- +* Charts with sensor data can be requested in one of the supported [`vega-lite themes `_] (incl. a dark theme) [see `PR #221 `_] Bugfixes ----------- diff --git a/flexmeasures/ui/templates/views/sensors.html b/flexmeasures/ui/templates/views/sensors.html index c8efd6c81..c71387d9f 100644 --- a/flexmeasures/ui/templates/views/sensors.html +++ b/flexmeasures/ui/templates/views/sensors.html @@ -30,13 +30,8 @@ let vegaView; async function embedAndLoad(chartSpecsPath, elementId, datasetName) { - var opt = { - mode: 'vega-lite', - renderer: 'svg', - actions: {export: true, source: true, editor: true}, - }; - await vegaEmbed('#'+elementId, chartSpecsPath + '?dataset_name=' + datasetName, opt) + await vegaEmbed('#'+elementId, chartSpecsPath + '?dataset_name=' + datasetName, {{ chart_options | safe }}) .then(function (result) { // result.view is the Vega View, chartSpecsPath is the original Vega-Lite specification vegaView = result.view; diff --git a/flexmeasures/ui/utils/chart_defaults.py b/flexmeasures/ui/utils/chart_defaults.py new file mode 100644 index 000000000..959bc5cdb --- /dev/null +++ b/flexmeasures/ui/utils/chart_defaults.py @@ -0,0 +1,7 @@ +chart_options = dict( + mode="vega-lite", + renderer="svg", + actions={"export": True, "source": True, "editor": True}, + theme="light", + tooltip={"theme": "light"}, +) diff --git a/flexmeasures/ui/utils/view_utils.py b/flexmeasures/ui/utils/view_utils.py index 8493ba7e9..d58a8b15d 100644 --- a/flexmeasures/ui/utils/view_utils.py +++ b/flexmeasures/ui/utils/view_utils.py @@ -1,4 +1,5 @@ """Utilities for views""" +import json import os import subprocess from typing import Tuple, List, Optional @@ -19,6 +20,7 @@ from flexmeasures.data.models.markets import Market from flexmeasures.data.models.weather import WeatherSensorType from flexmeasures.data.services.resources import Resource +from flexmeasures.ui.utils.chart_defaults import chart_options def render_flexmeasures_template(html_filename: str, **variables): @@ -89,6 +91,7 @@ def render_flexmeasures_template(html_filename: str, **variables): current_user.is_authenticated and current_user.username or "" ) variables["js_versions"] = current_app.config.get("FLEXMEASURES_JS_VERSIONS") + variables["chart_options"] = json.dumps(chart_options) variables["menu_logo"] = current_app.config.get("FLEXMEASURES_MENU_LOGO_PATH") variables["extra_css"] = current_app.config.get("FLEXMEASURES_EXTRA_CSS_PATH") diff --git a/flexmeasures/ui/views/sensors.py b/flexmeasures/ui/views/sensors.py index 0f6593e50..61ff3c536 100644 --- a/flexmeasures/ui/views/sensors.py +++ b/flexmeasures/ui/views/sensors.py @@ -10,6 +10,7 @@ from flexmeasures.data.schemas.times import AwareDateTimeField from flexmeasures.api.dev.sensors import SensorAPI from flexmeasures.ui.utils.view_utils import render_flexmeasures_template +from flexmeasures.ui.utils.chart_defaults import chart_options class SensorUI(FlaskView): @@ -30,15 +31,25 @@ class SensorUI(FlaskView): "beliefs_after": AwareDateTimeField(format="iso", required=False), "beliefs_before": AwareDateTimeField(format="iso", required=False), "dataset_name": fields.Str(required=False), + "chart_theme": fields.Str(required=False), }, location="query", ) def get_chart(self, id, **kwargs): """GET from /sensors//chart""" + + # Chart theme + chart_theme = kwargs.pop("chart_theme", None) + embed_options = chart_options.copy() + if chart_theme: + embed_options["theme"] = chart_theme + embed_options["tooltip"]["theme"] = chart_theme + + # Chart specs chart_specs = SensorAPI().get_chart(id, include_data=True, **kwargs) return spec_to_html( json.loads(chart_specs), - mode="vega-lite", + mode=embed_options["mode"], vega_version=current_app.config.get("FLEXMEASURES_JS_VERSIONS")["vega"], vegaembed_version=current_app.config.get("FLEXMEASURES_JS_VERSIONS")[ "vegaembed" @@ -46,6 +57,7 @@ def get_chart(self, id, **kwargs): vegalite_version=current_app.config.get("FLEXMEASURES_JS_VERSIONS")[ "vegalite" ], + embed_options=embed_options, ) @login_required