Skip to content

Commit

Permalink
feature: show a warning message whenever a heatmap is shown that mask…
Browse files Browse the repository at this point in the history
…s sources (#780)

Signed-off-by: F.N. Claessen <felix@seita.nl>
  • Loading branch information
Flix6x committed Aug 1, 2023
1 parent 12bac09 commit 60d8146
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
2 changes: 1 addition & 1 deletion flexmeasures/ui/static/css/flexmeasures.css
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ p.error {
font-weight: 700;
}

#tzwarn {
#tzwarn,#sourcewarn {
margin-top: 20px;
margin-bottom: 20px;
color: var(--secondary-color);
Expand Down
63 changes: 63 additions & 0 deletions flexmeasures/ui/static/js/data-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Data source utils

/**
* Extracts unique values of a specified nested property from an array of JSON objects.
*
* @param {Array} data - An array of JSON objects from which to extract unique values.
* @param {string} key - The dot-separated key representing the nested property (e.g., 'source.id').
* @returns {Array} An array containing the unique values of the specified nested property.
*
* @example
* const data = [
* {"id": 1, "name": "foo", "source": {"id": 4, "name": "bar"}},
* {"id": 2, "name": "baz", "source": {"id": 4, "name": "qux"}},
* {"id": 3, "name": "quux", "source": {"id": 5, "name": "corge"}}
* ];
*
* const key = 'source.id';
* const uniqueSourceIds = getUniqueValues(data, key);
* console.log(uniqueSourceIds); // Output: [4, 5]
*/
export function getUniqueValues(data, key) {
var lookup = {};
var items = data;
var results = [];

for (var item, i = 0; item = items[i++];) {
var val = getValueByNestedKey(item, key);

if (!(val in lookup)) {
lookup[val] = 1;
results.push(val);
}
}
return results;
}

/**
* Retrieves the value of a nested property in an object using a dot-separated key.
*
* @param {Object} obj - The input JavaScript object from which to retrieve the nested value.
* @param {string} key - The dot-separated key representing the nested property (e.g., 'source.id').
* @returns {*} The value of the nested property if found, otherwise, returns undefined.
*
* @example
* const jsonString = '{"id":11,"name":"ajax","subject":"OR","mark":63,"source":{"id":4,"name":"foo"}}';
* const jsonObject = JSON.parse(jsonString);
*
* const key = 'source.id';
* const sourceId = getValueByNestedKey(jsonObject, key);
* console.log(sourceId); // Output: 4
*/
function getValueByNestedKey(obj, key) {
const keys = key.split('.');
let value = obj;
for (const k of keys) {
if (value[k] === undefined) {
return undefined; // Property not found
}
value = value[k];
}
return value;
}

15 changes: 15 additions & 0 deletions flexmeasures/ui/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
<!-- Render Charts -->
<script type="module" type="text/javascript">

import { getUniqueValues } from "{{ url_for('flexmeasures_ui.static', filename='js/data-utils.js') }}";
import { subtract, thisMonth, lastNMonths, getOffsetBetweenTimezonesForDate } from "{{ url_for('flexmeasures_ui.static', filename='js/daterange-utils.js') }}";
import { partition, updateBeliefs, beliefTimedelta, setAbortableTimeout} from "{{ url_for('flexmeasures_ui.static', filename='js/replay-utils.js') }}";

Expand Down Expand Up @@ -280,13 +281,25 @@
}
});

function checkSourceMasking(data) {
var uniqueSourceIds = getUniqueValues(data, 'source.id');
if (chartType == 'daily_heatmap' && uniqueSourceIds.length > 1) {
document.getElementById('sourcewarn').style.display = 'block';
document.getElementById('sourcewarn').innerHTML = 'Please note that only data from the most prevalent source is shown.';
}
else {
document.getElementById('sourcewarn').style.display = 'none';
}
}

async function embedAndLoad(chartSpecsPath, elementId, datasetName, previousResult, startDate, endDate) {

await vegaEmbed('#'+elementId, chartSpecsPath + 'dataset_name=' + datasetName + '&width=container&include_sensor_annotations=false&include_asset_annotations=false&chart_type=' + chartType, {{ chart_options | safe }})
.then(function (result) {
// result.view is the Vega View, chartSpecsPath is the original Vega-Lite specification
vegaView = result.view;
if (previousResult) {
checkSourceMasking(previousResult);
var slicedPreviousResult = previousResult.filter(item => {
return item.event_start >= startDate.getTime() && item.event_start < endDate.getTime();
})
Expand Down Expand Up @@ -397,6 +410,7 @@
$("#spinner").hide();
vegaView.change(datasetName, vega.changeset().remove(vega.truthy).insert(result[0])).resize().run();
previousResult = result[0];
checkSourceMasking(previousResult);
/**
vegaView.change(datasetName + '_annotations', vega.changeset().remove(vega.truthy).insert(result[1])).resize().run();
*/
Expand All @@ -418,6 +432,7 @@
$("#spinner").hide();
vegaView.change(datasetName, vega.changeset().remove(vega.truthy).insert(fetchedInitialData)).resize().run();
previousResult = fetchedInitialData;
checkSourceMasking(previousResult);
var timerangeNotSetYet = false
{% else %}
var timerangeNotSetYet = true
Expand Down
5 changes: 4 additions & 1 deletion flexmeasures/ui/templates/views/sensors.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
{% block divs %}

<div class="sensor-data charts text-center">
<div class="row"><div class="alert alert-info" id="tzwarn" style="display:none;"></div></div>
<div class="row">
<div class="alert alert-info" id="tzwarn" style="display:none;"></div>
<div class="alert alert-info" id="sourcewarn" style="display:none;"></div>
</div>
<div class="row on-top-md">
<div class="col-sm-2">
<div class="sidepanel-container">
Expand Down

0 comments on commit 60d8146

Please sign in to comment.