better date parsing for candlestick

This commit is contained in:
Gerard Burns 2024-04-20 09:33:42 +01:00
parent 98cb16cc95
commit d7f9b1f5ee
5 changed files with 133 additions and 9 deletions

View File

@ -9,7 +9,6 @@
const updateTimeStamp = () => {
timestamp = Date.now();
console.log(timestamp);
if (run) {
setTimeout(updateTimeStamp, 200)
}
@ -25,7 +24,7 @@
<Subject heading="Dates as Numbers">
<Section>
A date can be used in place of a numeric value, but it will be parsed as a <Block>UNIX epoch</Block> timestamp, which is the number of milliseconds since Jan 1st 1970. A more recent moment in time will be a higher number.
A date can be used in place of a numeric value, but it will be parsed as a <Block>UNIX time</Block> timestamp, which is the number of milliseconds since Jan 1st 1970. A more recent moment in time will be a higher number.
</Section>
<ExampleSection

View File

@ -0,0 +1,50 @@
<script>
import { onMount } from "svelte"
import { ExampleSection, ExampleLine, Block, Subject, Section } from './components'
let timestamp = Date.now();
onMount(() => {
let run = true;
const updateTimeStamp = () => {
timestamp = Date.now();
console.log(timestamp);
if (run) {
setTimeout(updateTimeStamp, 200)
}
}
updateTimeStamp();
return () => {
run = false;
}
})
</script>
<Subject heading="Dates as Numbers">
<Section>
A date can be used in place of a numeric value, but it will be parsed as a <Block>UNIX epoch</Block> timestamp, which is the number of milliseconds since Jan 1st 1970. A more recent moment in time will be a higher number.
</Section>
<ExampleSection
heading="Examples:"
>
<ExampleLine>
1st Jan 2000<span class="separator">: </span><Block>946684800000</Block>
</ExampleLine>
<ExampleLine>
1st Jan 2020<span class="separator">: </span><Block>1577836800000</Block>
</ExampleLine>
<ExampleLine>
Now<span class="separator">:</span> <Block>{timestamp}</Block>
</ExampleLine>
</ExampleSection>
</Subject>
<style>
.separator {
margin-right: 5px;
}
</style>

View File

@ -110,7 +110,7 @@
offset={20}
>
<Explanation
explanationModal
showDetails
tableHref={`/builder/app/${$params.application}/data/table/${datasource?.tableId}`}
schema={schema[currentOption]}
columnIcon={getOptionIcon(currentOption)}

View File

@ -14,7 +14,7 @@
"skeletonLoader": true
},
"typeSupportPresets": {
"chartValue": {
"numberLike": {
"supported": ["number", "boolean"],
"partialSupport": [
{ "type": "longform", "message": "stringAsNumber" },
@ -27,6 +27,26 @@
"unsupported": [
{ "type": "json", "message": "jsonPrimitivesOnly" }
]
},
"datetimeLike": {
"supported": ["datetime"],
"partialSupport": [
{ "type": "longform", "message": "stringAsDate" },
{ "type": "string", "message": "stringAsDate" },
{ "type": "options", "message": "stringAsDate" },
{ "type": "formula", "message": "stringAsDate" },
{ "type": "bigint", "message": "stringAsDate" },
{ "type": "number", "message": "numberAsDate"}
],
"unsupported": [
{ "type": "json", "message": "jsonPrimitivesOnly" }
]
},
"stringLike": {
"supported": ["string", "number", "bigint", "options", "longform", "boolean", "datetime"],
"unsupported": [
{ "type": "json", "message": "jsonPrimitivesOnly" }
]
}
},
"layout": {
@ -1652,7 +1672,7 @@
"dependsOn": "dataProvider",
"explanation": {
"typeSupport": {
"preset": "chartValue"
"preset": "numberLike"
}
},
"required": true
@ -1816,7 +1836,7 @@
"dependsOn": "dataProvider",
"explanation": {
"typeSupport": {
"preset": "chartValue"
"preset": "numberLike"
}
},
"required": true
@ -1975,7 +1995,7 @@
"dependsOn": "dataProvider",
"explanation": {
"typeSupport": {
"preset": "chartValue"
"preset": "numberLike"
}
},
"required": true
@ -2144,6 +2164,11 @@
"label": "Data column",
"key": "valueColumn",
"dependsOn": "dataProvider",
"explanation": {
"typeSupport": {
"preset": "numberLike"
}
},
"required": true
},
{
@ -2274,6 +2299,11 @@
"label": "Data columns",
"key": "valueColumn",
"dependsOn": "dataProvider",
"explanation": {
"typeSupport": {
"preset": "numberLike"
}
},
"required": true
},
{
@ -2472,7 +2502,6 @@
"width": 600,
"height": 400
},
"requiredAncestors": ["dataprovider"],
"settings": [
{
"type": "text",
@ -2490,6 +2519,11 @@
"label": "Data column",
"key": "valueColumn",
"dependsOn": "dataProvider",
"explanation": {
"typeSupport": {
"preset": "numberLike"
}
},
"required": true
},
{

View File

@ -63,6 +63,47 @@
}
}
const getValueAsUnixEpoch = (dataprovider, dateColumn, row) => {
const value = row[dateColumn]
if (dataProvider?.schema?.[dateColumn]?.type === 'datetime') {
return Date.parse(value);
}
// Unix epoch
if (typeof value === "number") {
return value;
}
const isString = typeof value === "string";
// "2025" could be either an ISO 8601 date time string or Unix time.
// There's no way to tell the user's intent without providing more
// granular controls.
// We'll just assume any string without dashes is Unix time.
if (isString && value.includes("-")) {
const unixTime = Date.parse(value);
if (isNaN(unixTime)) {
return null
}
return unixTime
}
if (isString) {
const unixTime = parseInt(value, 10);
if (isNaN(unixTime)) {
return null
}
return unixTime
}
return null;
}
const getSeries = (
dataProvider,
dateColumn,
@ -81,7 +122,7 @@
const close = parseFloat(row[closeColumn])
return [
Date.parse(row[dateColumn]),
getValueAsUnixEpoch(dataProvider, dateColumn, row),
isNaN(open) ? 0 : open,
isNaN(high) ? 0 : high,
isNaN(low) ? 0 : low,