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" 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/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 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) }) }) })