Allow ISO Formatted string dates in charts svelte-component
mattmccormick opened this issue · 3 comments
I'm trying to write a Fava extension. The extension would display a line chart using the following code:
{% set chart_data = [{'type': 'balances', 'label': 'Chart', 'data': extension.data()}] %}
<svelte-component type="charts">
<script id="chart-data" type="application/json">{{chart_data|tojson}}</script>
</svelte-component>
The issue is that the LineChartDatum
must be a native JS Date object
fava/frontend/src/charts/line.ts
Line 16 in 528f818
However, it is not possible to use a date string as the component will fail with the following error:
Rendering component 'charts' failed due to invalid JSON data:
Parsing of data for balances chart failed:
Validating object failed at key 'date': Expected a date
Allow ISO Formatted string dates in charts svelte-component
That is already the case - JSON data is loaded via validators, which try to convert from e.g. a string to a Date. The error comes from the function
fava/frontend/src/lib/validation.ts
Line 65 in 528f818
Can you provide some example data that fails loading?
Here's a test plugin that should reproduce the issue.
test_plugin/templates/TestPlugin.html
{% set chart_data = [{'type': 'balances', 'label': 'Chart', 'data': extension.data()}] %}
<svelte-component type="charts">
<script id="chart-data" type="application/json">{{chart_data|tojson}}</script>
</svelte-component>
test_plugin/__init__.py
from datetime import datetime
from fava.ext import FavaExtensionBase
class TestPlugin(FavaExtensionBase):
report_title = 'Test Plugin'
def data(self):
return [
{
'name': 'Chart',
'values': [
{'name': 'Value', 'date': datetime.now().isoformat(), 'value': 2}
]
}
]
In the .beancount file, add:
2000-01-01 custom "fava-extension" "test_plugin"
When clicking on the Test Plugin
link in the left side navbar, the page should display the following error:
Rendering component 'charts' failed due to invalid JSON data:
Parsing of data for balances chart failed:
Validating object failed at key 'date': Expected a date
The generated HTML should be:
<svelte-component type="charts">
<script id="chart-data" type="application/json">[
{
"data": [
{
"name": "Chart",
"values": [
{
"date": "2024-05-26T09:05:12.097824",
"name": "Value",
"value": 2
}
]
}
],
"label": "Chart",
"type": "balances"
}
]</script>
A date is expected there, not a datetime - so calling date()
on that datetime before serialising it should do the trick. In theory, so far anything the Javascript Date constructor accepted would have worked, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format - due to the timezone inconsistencies in parsing though, that's not really desirable, I'll tighten the validation there.