Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subgraph improvements #5

Merged
merged 3 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/services/mock/json/workflows/multi.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
47 changes: 32 additions & 15 deletions src/utils/graph-utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
Expand All @@ -15,25 +15,42 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* 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
Expand Down
34 changes: 18 additions & 16 deletions src/views/Graph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/>
</g>
</g>
<g v-if="groupCycle" class="graph-subgraph-container">
<g v-for="(subgraph, key) in subgraphs"
:key="key">
<GraphSubgraph
v-if="subgraph.label!='margin'"
:subgraph="subgraph" />
</g>
<g v-if="groupCycle">
<GraphSubgraph
v-for="(subgraph, key) in subgraphs"
:key="key"
:subgraph="subgraph"
/>
</g>
</g>
</svg>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 13 additions & 3 deletions tests/unit/utils/graph-utils.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -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)
})
})
})
Loading