From 0eb52f08173d32dee7f449987be7a86968d769e4 Mon Sep 17 00:00:00 2001
From: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Date: Tue, 14 May 2024 18:53:45 +0100
Subject: [PATCH 1/3] Tidy
---
src/views/Graph.vue | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/views/Graph.vue b/src/views/Graph.vue
index d35f93e36..847785bb6 100644
--- a/src/views/Graph.vue
+++ b/src/views/Graph.vue
@@ -86,13 +86,12 @@ along with this program. If not, see .
/>
-
-
-
-
+
+
@@ -514,7 +513,7 @@ export default {
* Get the nodes binned by cycle point
*
* @param {Object[]} nodes
- * @returns {{ [dateTime: string]: Object[] nodes }} mapping of node to their cycle point.
+ * @returns {{ [dateTime: string]: Object[] }=} mapping of cycle points to nodes
*/
getCycles (nodes) {
if (!this.groupCycle) return
@@ -764,14 +763,17 @@ export default {
// update graph node positions
for (const obj of json.objects) {
if (obj.bb) {
- // if the object is a subgraph
- const [left, bottom, right, top] = obj.bb.split(',')
- this.subgraphs[obj.name] = {
- x: left,
- y: -top,
- width: right - left,
- height: top - bottom,
- label: obj.label
+ // if the object is a subgraph
+ if (obj.label !== 'margin') {
+ // ignore the margins in the dot-code which do not need DOM elements
+ const [left, bottom, right, top] = obj.bb.split(',')
+ this.subgraphs[obj.name] = {
+ x: left,
+ y: -top,
+ width: right - left,
+ height: top - bottom,
+ label: obj.label
+ }
}
} else {
// else the object is a node
From b7059c25e53519249712c9402a739a75b8bab15f Mon Sep 17 00:00:00 2001
From: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Date: Tue, 14 May 2024 19:14:02 +0100
Subject: [PATCH 2/3] Mock data: update subscription data for graph view
---
src/services/mock/json/workflows/multi.json | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/services/mock/json/workflows/multi.json b/src/services/mock/json/workflows/multi.json
index 871918d17..89c6a3721 100644
--- a/src/services/mock/json/workflows/multi.json
+++ b/src/services/mock/json/workflows/multi.json
@@ -141,9 +141,11 @@
{
"id": "~user/other/multi/run2//1/foo",
"state": "waiting",
+ "cyclePoint": "1",
"isHeld": false,
"isQueued": true,
"isRunahead": false,
+ "name": "foo",
"task": {
"meanElapsedTime": 0,
"__typename": "Task"
@@ -157,9 +159,11 @@
{
"id": "~user/other/multi/run2//2/foo",
"state": "waiting",
+ "cyclePoint": "2",
"isHeld": false,
"isQueued": false,
"isRunahead": false,
+ "name": "foo",
"task": {
"meanElapsedTime": 0,
"__typename": "Task"
From 44b8ca04da4f1acd8cace0e048b49a0a65e841f8 Mon Sep 17 00:00:00 2001
From: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Date: Wed, 15 May 2024 13:18:32 +0100
Subject: [PATCH 3/3] Graph view: handle negative coords when converting
graphviz edge to SVG
---
src/utils/graph-utils.js | 47 +++++++++++++++++++---------
tests/unit/utils/graph-utils.spec.js | 16 ++++++++--
2 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/src/utils/graph-utils.js b/src/utils/graph-utils.js
index 76a369be1..40bd39a0d 100644
--- a/src/utils/graph-utils.js
+++ b/src/utils/graph-utils.js
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
@@ -15,25 +15,42 @@
* along with this program. If not, see .
*/
+/**
+ * Convert graphviz edge bezier curve in dot format to SVG path .
+ *
+ * @param {string} pos - `pos` attribute of a graph edge in dot format.
+ * @returns {string} The SVG path.
+ */
export function posToPath (pos) {
+ // pos starts with `e,` followed by a list of coordinates
+ const parts = pos.substring(2).split(' ')
// the last point comes first, followed by the others in order I.E:
// -1, 0, 1, 2, ... -3, -2
- const parts = pos.substring(2).split(' ').map(x => x.split(','))
- const [last] = parts.splice(0, 1)
- let path = null
- for (const part of parts) {
- if (!path) {
- path = `M${part[0]} -${part[1]} C`
- } else {
- path = path + ` ${part[0]} -${part[1]},`
- }
- }
- path = path + ` L ${last[0]} -${last[1]}`
- return path
+ const [last, first] = parts.splice(0, 2)
+ const path = parts.reduce(
+ (acc, part) => `${acc} ${getCoord(part)},`,
+ `M${getCoord(first)} C`
+ )
+ return `${path} L ${getCoord(last)}`
}
-/* TODO: everything! */
-// eslint-disable-next-line no-extend-native
+/**
+ * Convert dotcode `pos` coordinate to SVG path coordinate.
+ *
+ * @param {string} posCoord - A coordinate in dot format.
+ * @returns {string}
+ */
+export function getCoord (posCoord) {
+ const [x, y] = posCoord.split(',').map(parseFloat)
+ return `${x} ${-y}`
+}
+
+/**
+ * Calculate a non-cryptographic hash value for a given string.
+ *
+ * @param {string} string
+ * @returns {number}
+ */
export function nonCryptoHash (string) {
let hash = 0
let i
diff --git a/tests/unit/utils/graph-utils.spec.js b/tests/unit/utils/graph-utils.spec.js
index 0f8b56199..4cc556ab6 100644
--- a/tests/unit/utils/graph-utils.spec.js
+++ b/tests/unit/utils/graph-utils.spec.js
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
@@ -39,11 +39,21 @@ describe('Graph functionality', () => {
'L 211.5 -156.5'
)
})
+ it('Handles negative coordinates', () => {
+ expect(posToPath(
+ 'e,1,1 -2,-2 3,-3 -1,-0'
+ )).to.equal(
+ 'M-2 2 C 3 3, -1 0, L 1 -1'
+ )
+ })
})
describe('nonCryptoHash', () => {
- it('Converts a string to a stable hash', () => {
- expect(nonCryptoHash('foo')).to.equal(101574)
+ it.each([
+ ['foo', 101574],
+ ['', 0],
+ ])('Converts a string to a stable hash: %o -> %i', (str, expected) => {
+ expect(nonCryptoHash(str)).to.equal(expected)
})
})
})