From f2d9f3251d97b258c2a0022e7dc207b91139bcc2 Mon Sep 17 00:00:00 2001 From: Arild Matsson Date: Wed, 25 Sep 2024 18:54:55 +0200 Subject: [PATCH] refactor(ts): trend-diagram/util --- app/scripts/components/trend-diagram.js | 36 ++------- .../trend_util.js => trend-diagram/util.ts} | 81 +++++++++++-------- 2 files changed, 55 insertions(+), 62 deletions(-) rename app/scripts/{trend_diagram/trend_util.js => trend-diagram/util.ts} (54%) diff --git a/app/scripts/components/trend-diagram.js b/app/scripts/components/trend-diagram.js index b8c8faa72..540c73ba5 100644 --- a/app/scripts/components/trend-diagram.js +++ b/app/scripts/components/trend-diagram.js @@ -8,29 +8,9 @@ import graphProxyFactory from "@/backend/graph-proxy" import { expandOperators } from "@/cqp_parser/cqp" import { formatRelativeHits, hitCountHtml, html } from "@/util" import { loc } from "@/i18n" -import * as trendUtil from "../trend_diagram/trend_util" +import { formatUnixDate, getTimeCqp, GRANULARITIES, parseDate, LEVELS, FORMATS } from "@/trend-diagram/util" import "@/components/korp-error" -const granularities = { - year: "y", - month: "m", - day: "d", - hour: "h", - minute: "n", - second: "s", -} - -const zoomLevelToFormat = { - second: "YYYY-MM-DD hh:mm:ss", - minute: "YYYY-MM-DD hh:mm", - hour: "YYYY-MM-DD hh", - day: "YYYY-MM-DD", - month: "YYYY-MM", - year: "YYYY", -} - -const validZoomLevels = Object.keys(granularities) - angular.module("korpApp").component("trendDiagram", { template: html` @@ -118,7 +98,7 @@ angular.module("korpApp").component("trendDiagram", { return } - const timecqp = trendUtil.getTimeCQP(time, zoom, validZoomLevels.indexOf(zoom) < 3) + const timecqp = getTimeCqp(time, zoom, LEVELS.indexOf(zoom) < 3) const decodedCQP = decodeURIComponent(cqp) const opts = { ajaxParams: { @@ -161,7 +141,7 @@ angular.module("korpApp").component("trendDiagram", { const fmt = "YYYYMMDDHHmmss" drawPreloader(from, to) - $ctrl.proxy.granularity = granularities[zoom] + $ctrl.proxy.granularity = GRANULARITIES[zoom] makeRequest( $ctrl.data.cqp, $ctrl.data.subcqps, @@ -183,7 +163,7 @@ angular.module("korpApp").component("trendDiagram", { const oldZoom = $ctrl.zoom const idealNumHits = 1000 - let newZoom = _.minBy(validZoomLevels, function (zoom) { + let newZoom = _.minBy(LEVELS, function (zoom) { const nPoints = to.diff(from, zoom) return Math.abs(idealNumHits - nPoints) }) @@ -232,7 +212,7 @@ angular.module("korpApp").component("trendDiagram", { let output = [] for (let [x, y] of _.toPairs(data)) { - const mom = trendUtil.parseDate($ctrl.zoom, x) + const mom = parseDate($ctrl.zoom, x) output.push({ x: mom, y }) } @@ -347,7 +327,7 @@ angular.module("korpApp").component("trendDiagram", { const header = [loc("stats_hit")] for (let cell of series[0].data) { - const stampformat = zoomLevelToFormat[cell.zoom] + const stampformat = FORMATS[cell.zoom] header.push(moment(cell.x * 1000).format(stampformat)) } @@ -391,7 +371,7 @@ angular.module("korpApp").component("trendDiagram", { for (let row of series) { const new_time_row = { label: row.name } for (let item of row.data) { - const stampformat = zoomLevelToFormat[item.zoom] + const stampformat = FORMATS[item.zoom] const timestamp = moment(item.x * 1000).format(stampformat) // this needs to be fixed for other resolutions time_table_columns_intermediate[timestamp] = { name: timestamp, @@ -643,7 +623,7 @@ angular.module("korpApp").component("trendDiagram", { // formatter is only called once per per "hover detail creation" graph, xFormatter(x) { - return `${trendUtil.formatUnixDate($ctrl.zoom, x)}` + return `${formatUnixDate($ctrl.zoom, x)}` }, yFormatter(y) { diff --git a/app/scripts/trend_diagram/trend_util.js b/app/scripts/trend-diagram/util.ts similarity index 54% rename from app/scripts/trend_diagram/trend_util.js rename to app/scripts/trend-diagram/util.ts index d5373ab70..7f014b665 100644 --- a/app/scripts/trend_diagram/trend_util.js +++ b/app/scripts/trend-diagram/util.ts @@ -1,9 +1,48 @@ /** @format */ +import { Granularity } from "@/backend/types" import moment from "moment" -export function getTimeCQP(time, zoom, coarseGranularity) { - let timecqp - const m = moment(time * 1000) +export type Level = "year" | "month" | "day" | "hour" | "minute" | "second" + +/** + * Mapping from long to short form of granularities. + * Moment uses the long form, and Korp API uses the short form. + */ +export const GRANULARITIES: Record = { + year: "y", + month: "m", + day: "d", + hour: "h", + minute: "n", + second: "s", +} + +/** Granularities by descending size order */ +export const LEVELS: Level[] = ["year", "month", "day", "hour", "minute", "second"] + +/** How to express dates of different granularities */ +export const FORMATS: Record = { + second: "YYYY-MM-DD hh:mm:ss", + minute: "YYYY-MM-DD hh:mm", + hour: "YYYY-MM-DD hh:00", + day: "YYYY-MM-DD", + month: "YYYY-MM", + year: "YYYY", +} + +/** Timestamps come from backend in these shapes */ +const PARSE_FORMATS: Record = { + second: "YYYYMMDDHHmmss", + minute: "YYYYMMDDHHmm", + hour: "YYYYMMDDHH", + day: "YYYYMMDD", + month: "YYYYMM", + year: "YYYY", +} + +export function getTimeCqp(timeUnix: number, zoom: Level, coarseGranularity?: boolean) { + let timecqp: string + const m = moment(timeUnix * 1000) const datefrom = moment(m).startOf(zoom).format("YYYYMMDD") const dateto = moment(m).endOf(zoom).format("YYYYMMDD") @@ -34,38 +73,12 @@ export function getTimeCQP(time, zoom, coarseGranularity) { return timecqp } -export function parseDate(zoom, time) { - switch (zoom) { - case "year": - return moment(time, "YYYY") - case "month": - return moment(time, "YYYYMM") - case "day": - return moment(time, "YYYYMMDD") - case "hour": - return moment(time, "YYYYMMDDHH") - case "minute": - return moment(time, "YYYYMMDDHHmm") - case "second": - return moment(time, "YYYYMMDDHHmmss") - } +export function parseDate(zoom: Level, time: string) { + return moment(time, PARSE_FORMATS[zoom]) } -export function formatUnixDate(zoom, time) { +export function formatUnixDate(zoom: Level, time: number) { // TODO this should respect locale and could present whole months as August 2020 instead of 2020-08 - const m = moment.unix(String(time)) - switch (zoom) { - case "year": - return m.format("YYYY") - case "month": - return m.format("YYYY-MM") - case "day": - return m.format("YYYY-MM-DD") - case "hour": - return m.format("YYYY-MM-DD HH:00") - case "minute": - return m.format("YYYY-MM-DD HH:mm") - case "second": - return m.format("YYYY-MM-DD HH:mm:ss") - } + const m = moment.unix(time) + return m.format(FORMATS[zoom]) }