From ab5f5986dc924d28542bb7da19325e95bffb0958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Thu, 11 May 2023 18:53:33 +0200 Subject: [PATCH] fix: apply typing fixes needed after updating dependencies --- src/queries.ts | 2 +- src/views/Buckets.vue | 2 +- src/views/Graph.vue | 4 +- src/views/settings/CategoryBuilder.vue | 5 +- src/visualizations/ForceGraph.vue | 76 ++++++++++++++++++-------- src/visualizations/Timespiral.vue | 12 ++-- 6 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/queries.ts b/src/queries.ts index 95b17606..9f5ca62c 100644 --- a/src/queries.ts +++ b/src/queries.ts @@ -39,7 +39,7 @@ interface DesktopQueryParams extends BaseQueryParams { bid_window: string; bid_afk: string; filter_afk: boolean; - always_active_pattern: string; + always_active_pattern?: string; } interface AndroidQueryParams extends BaseQueryParams { diff --git a/src/views/Buckets.vue b/src/views/Buckets.vue index d8bff042..f03f61fd 100644 --- a/src/views/Buckets.vue +++ b/src/views/Buckets.vue @@ -187,7 +187,7 @@ export default { const bucket = await this.bucketsStore.getBucketWithEvents({ id: bucketId }); const events = bucket.events; const datakeys = Object.keys(events[0].data); - const columns = ['timestamp', 'duration'] + datakeys; + const columns = ['timestamp', 'duration'].concat(datakeys); const data = events.map(e => { return Object.assign( { timestamp: e.timestamp, duration: e.duration }, diff --git a/src/views/Graph.vue b/src/views/Graph.vue index 6d3dfe64..d746c95a 100644 --- a/src/views/Graph.vue +++ b/src/views/Graph.vue @@ -155,7 +155,9 @@ export default { return { ...e, data: { ...e.data, $category } }; }); - const allCategories = new Set(events.map(e => e.data.$category).map(c => c.join(SEP))); + const allCategories: Set = new Set( + events.map(e => e.data.$category).map(c => c.join(SEP)) + ); const groups = { Uncategorized: 0 }; // Generate groups diff --git a/src/views/settings/CategoryBuilder.vue b/src/views/settings/CategoryBuilder.vue index b849d2bf..9d2a9ea4 100644 --- a/src/views/settings/CategoryBuilder.vue +++ b/src/views/settings/CategoryBuilder.vue @@ -153,7 +153,8 @@ export default { computed: { ...mapState(useCategoryStore, ['allCategoriesSelect']), words_by_duration: function () { - return Object.values(this.words) + const words: { [key: string]: { word: string; duration: number } } = this.words; + return Object.values(words) .sort((a, b) => b.duration - a.duration) .filter(word => word.duration > 60) .filter(word => !this.ignored_words.includes(word.word)); @@ -282,7 +283,7 @@ export default { // Find the category with the max ID, and open an editor for it const lastId = _.max(_.map(this.categoryStore.classes, 'id')); - this.create.word = word.word; + this.create.word = word; this.create.categoryId = lastId; }, async createRuleOk() { diff --git a/src/visualizations/ForceGraph.vue b/src/visualizations/ForceGraph.vue index 8e5710c0..28ab7d0c 100644 --- a/src/visualizations/ForceGraph.vue +++ b/src/visualizations/ForceGraph.vue @@ -40,7 +40,8 @@ export default { }); const svgEl = ForceGraph({ nodes, links }, { invalidation: promise }); - const svg = d3.select('#forcegraph'); + const svg: d3.Selection = + d3.select('#forcegraph'); //clear svg.selectAll('*').remove(); //append @@ -50,6 +51,25 @@ export default { }, }; +type GNode = { + id: string; + color: string; + value: number; + radius?: number; +}; + +type GLinkEnd = { + index: number; + x: number; + y: number; +}; + +type GLink = { + source: GLinkEnd; + target: GLinkEnd; + value: number; +}; + // Copyright 2021 Observable, Inc. // Released under the ISC license. // https://observablehq.com/@d3/force-directed-graph @@ -57,18 +77,21 @@ function ForceGraph( { nodes, // an iterable of node objects (typically [{id}, …]) links, // an iterable of link objects (typically [{source, target}, …]) + }: { + nodes: GNode[]; + links: GLink[]; }, { nodeId = d => d.id, // given d in nodes, returns a unique identifier (string) nodeGroup = d => d.group, // given d in nodes, returns an (ordinal) value for color - nodeGroups, // an array of ordinal values representing the node groups - nodeTitle = d => d.id.split('>').slice(-1), // given d in nodes, a title string + nodeGroups = undefined, // an array of ordinal values representing the node groups + nodeTitle = null, // given d in nodes, a title string nodeFill = 'currentColor', // node stroke fill (if not using a group color encoding) nodeStroke = '#fff', // node stroke color nodeStrokeWidth = 1.5, // node stroke width, in pixels nodeStrokeOpacity = 1, // node stroke opacity nodeRadius = 4, // node radius, in pixels - nodeStrength, + nodeStrength = undefined, linkSource = ({ source }) => source, // given d in links, returns a node identifier string linkTarget = ({ target }) => target, // given d in links, returns a node identifier string linkStroke = '#999', // link stroke color @@ -87,13 +110,13 @@ function ForceGraph( colors = d3.schemeTableau10, // an array of color strings, for the node groups width = 640, // outer width, in pixels height = 400, // outer height, in pixels - invalidation, // when this promise resolves, stop the simulation + invalidation = null, // when this promise resolves, stop the simulation } = {} ) { // Compute values. - const N = d3.map(nodes, nodeId).map(intern); - const LS = d3.map(links, linkSource).map(intern); - const LT = d3.map(links, linkTarget).map(intern); + const N: string[] = d3.map(nodes, nodeId).map(intern); + const LS: GLinkEnd[] = d3.map(links, linkSource).map(intern); + const LT: GLinkEnd[] = d3.map(links, linkTarget).map(intern); if (nodeTitle === undefined) nodeTitle = (_, i) => N[i]; const T = nodeTitle == null ? null : d3.map(nodes, nodeTitle); const G = nodeGroup == null ? null : d3.map(nodes, nodeGroup).map(intern); @@ -101,8 +124,12 @@ function ForceGraph( const L = typeof linkStroke !== 'function' ? null : d3.map(links, linkStroke); // Replace the input nodes and links with mutable objects for the simulation. - nodes = d3.map(nodes, (node, i) => ({ id: N[i], color: node.color, value: node.value })); - links = d3.map(links, (link, i) => ({ source: LS[i], target: LT[i], value: link.value })); + nodes = d3.map(nodes, (node, i) => ({ + id: N[i], + color: node.color, + value: node.value, + })); + links = d3.map(links, ({ value }, i) => ({ source: LS[i], target: LT[i], value })); // Scale so that the area of each node is ~proportional to the time value nodes = nodes.map(d => { @@ -123,13 +150,13 @@ function ForceGraph( if (linkStrength !== undefined) forceLink.strength(linkStrength); const simulation = d3 - .forceSimulation(nodes) + .forceSimulation(nodes as any) .force('link', forceLink) .force('charge', forceNode) .force('center', d3.forceCenter()) .force( 'collision', - d3.forceCollide(d => d.radius) + d3.forceCollide((d: any) => d.radius) ) .on('tick', ticked); @@ -137,10 +164,10 @@ function ForceGraph( .create('svg') .attr('width', width) .attr('height', height) - .attr('viewBox', [-width / 2, -height / 2, width, height]) + .attr('viewBox', [-width / 2, -height / 2, width, height] as any) .attr('style', 'max-width: 100%; height: auto; height: intrinsic;'); - const link = svg + const link: d3.Selection = svg .append('g') .attr('stroke', typeof linkStroke !== 'function' ? linkStroke : null) .attr('stroke-opacity', linkStrokeOpacity) @@ -160,13 +187,14 @@ function ForceGraph( .data(nodes) .join('circle') .attr('r', d => d.radius) - .call(drag(simulation)); + .call(drag(simulation) as any); - if (W) link.attr('stroke-width', ({ index: i }) => W[i]); - if (L) link.attr('stroke', ({ index: i }) => L[i]); + // FIXME: These type casts are a workaround + if (W) link.attr('stroke-width', (({ index: i }) => W[i]) as any); + if (L) link.attr('stroke', (({ index: i }) => L[i]) as any); //if (G) node.attr('fill', ({ index: i }) => color(G[i])); - node.attr('fill', ({ index: i }) => nodes[i].color); - if (T) node.append('title').text(({ index: i }) => T[i]); + node.attr('fill', (({ index: i }) => nodes[i].color) as any); + if (T) node.append('title').text((({ index: i }) => T[i]) as any); if (invalidation != null) invalidation.then(() => simulation.stop()); function intern(value) { @@ -175,12 +203,12 @@ function ForceGraph( function ticked() { link - .attr('x1', d => d.source.x) - .attr('y1', d => d.source.y) - .attr('x2', d => d.target.x) - .attr('y2', d => d.target.y); + .attr('x1', d => (d as any).source.x) + .attr('y1', d => (d as any).source.y) + .attr('x2', d => (d as any).target.x) + .attr('y2', d => (d as any).target.y); - node.attr('cx', d => d.x).attr('cy', d => d.y); + node.attr('cx', d => (d as any).x).attr('cy', d => (d as any).y); } function drag(_simulation) { diff --git a/src/visualizations/Timespiral.vue b/src/visualizations/Timespiral.vue index 3a10a0e8..ecc05f80 100644 --- a/src/visualizations/Timespiral.vue +++ b/src/visualizations/Timespiral.vue @@ -151,11 +151,11 @@ export default { const _domain_end = moment(eventdomain[1]).endOf('day'); // Limit the events to max_days - let domain; + let domain: [Date, Date]; if (_domain_end.clone().diff(_domain_start) / 1000 > max_days) { - domain = [_domain_end.clone().subtract(max_days, 'days'), _domain_end]; + domain = [_domain_end.clone().subtract(max_days, 'days').toDate(), _domain_end.toDate()]; } else { - domain = [_domain_start, _domain_end]; + domain = [_domain_start.toDate(), _domain_end.toDate()]; } const nbSpirals = Math.ceil( (domain[1].valueOf() - domain[0].valueOf()) / (24 * 60 * 60 * 1000) @@ -210,7 +210,7 @@ export default { // Computes the radius and spiral thickness for a particular event. // Each inner spiral (previous day) should get progressively thinner. - function spiralThickness(timestamp: string, staggered: boolean): [number, number] { + function spiralThickness(timestamp: Date, staggered = false): [number, number] { const hourstart = staggered ? moment(timestamp).startOf('hour').valueOf() : moment(timestamp).valueOf(); @@ -279,7 +279,7 @@ export default { // Draw clock ticks // Modified from sunburst-clock.js - function drawClockTick(group, a, radius, inner: boolean) { + function drawClockTick(group, a, radius, inner = false) { const xn = Math.cos(a); const yn = Math.sin(a); @@ -307,7 +307,7 @@ export default { .style('stroke-width', 2); } - function drawClock(group, h, m, text, radius, inner: boolean) { + function drawClock(group, h, m, text, radius, inner = false) { const a = 2 * Math.PI * (h / 24 + m / 24 / 60) - (1 / 2) * Math.PI; drawClockTick(g, a, radius, inner);