Skip to content

Commit 23c9e1e

Browse files
authored
Merge pull request #20 from common-workflow-language/visualisation
Visualisation
2 parents 322c260 + 2624c77 commit 23c9e1e

File tree

264 files changed

+39461
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

264 files changed

+39461
-6
lines changed

src/main/java/org/commonwl/viewer/domain/CWLCollection.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ private void findMainWorkflow() {
132132
// TODO: Consider relationship between run: parameters to better discover this
133133
for (int i=0; i < cwlDocs.size(); i++) {
134134
if (cwlDocs.get(i).get("class").asText().equals("Workflow")) {
135-
mainWorkflowIndex = i;
135+
mainWorkflowIndex = 0;
136+
return;
136137
}
137138
}
138139
}

src/main/java/org/commonwl/viewer/domain/Workflow.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@
1919

2020
package org.commonwl.viewer.domain;
2121

22+
import org.commonwl.viewer.services.DotWriter;
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
2225
import org.springframework.data.annotation.Id;
2326
import org.springframework.format.annotation.DateTimeFormat;
2427

28+
import java.io.IOException;
29+
import java.io.StringWriter;
2530
import java.nio.file.Path;
2631
import java.util.Date;
2732
import java.util.Map;
@@ -31,6 +36,8 @@
3136
*/
3237
public class Workflow {
3338

39+
static private final Logger logger = LoggerFactory.getLogger(Workflow.class);
40+
3441
// ID for database
3542
@Id
3643
private String id;
@@ -47,11 +54,24 @@ public class Workflow {
4754
private Map<String, CWLElement> inputs;
4855
private Map<String, CWLElement> outputs;
4956

57+
// DOT graph of the contents
58+
private String dotGraph = "test";
59+
5060
public Workflow(String label, String doc, Map<String, CWLElement> inputs, Map<String, CWLElement> outputs) {
5161
this.label = label;
5262
this.doc = doc;
5363
this.inputs = inputs;
5464
this.outputs = outputs;
65+
66+
// Create a DOT graph for this workflow and store it
67+
StringWriter graphWriter = new StringWriter();
68+
DotWriter dotWriter = new DotWriter(graphWriter);
69+
try {
70+
dotWriter.writeGraph(this);
71+
this.dotGraph = graphWriter.toString();
72+
} catch (IOException ex) {
73+
logger.error("Failed to create DOT graph for workflow: " + ex.getMessage());
74+
}
5575
}
5676

5777
@Override
@@ -122,4 +142,12 @@ public Date getRetrievedOn() {
122142
public void setRetrievedOn(Date retrievedOn) {
123143
this.retrievedOn = retrievedOn;
124144
}
145+
146+
public String getDotGraph() {
147+
return dotGraph;
148+
}
149+
150+
public void setDotGraph(String dotGraph) {
151+
this.dotGraph = dotGraph;
152+
}
125153
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.commonwl.viewer.services;
21+
22+
import org.commonwl.viewer.domain.CWLElement;
23+
import org.commonwl.viewer.domain.Workflow;
24+
25+
import java.io.IOException;
26+
import java.io.Writer;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
import java.util.Map;
30+
31+
/**
32+
* Writes GraphViz DOT files from Workflows
33+
*/
34+
public class DotWriter {
35+
36+
private static final String EOL = System.getProperty("line.separator");
37+
private Writer writer;
38+
39+
public DotWriter(Writer writer) {
40+
this.writer = writer;
41+
}
42+
43+
/**
44+
* Write a graph representing a workflow to the Writer
45+
* @param workflow The workflow to be graphed
46+
* @throws IOException Any errors in writing which may have occurred
47+
*/
48+
public void writeGraph(Workflow workflow) throws IOException {
49+
50+
/**
51+
* DOT graph styling is based on the Apache
52+
* Taverna workflow management system
53+
*/
54+
// Begin graph
55+
writeLine("digraph workflow {");
56+
57+
// Overall graph style
58+
writeLine(" graph [");
59+
writeLine(" bgcolor = \"#EEEEEE\"");
60+
writeLine(" color = \"black\"");
61+
writeLine(" fontsize = \"10\"");
62+
writeLine(" labeljust = \"left\"");
63+
writeLine(" clusterrank = \"local\"");
64+
writeLine(" ranksep = \"0.22\"");
65+
writeLine(" nodesep = \"0.05\"");
66+
writeLine(" ]");
67+
68+
// Overall node style
69+
writeLine(" node [");
70+
writeLine(" fontname = \"Helvetica\"");
71+
writeLine(" fontsize = \"10\"");
72+
writeLine(" fontcolor = \"black\"");
73+
writeLine(" shape = \"record\"");
74+
writeLine(" height = \"0\"");
75+
writeLine(" width = \"0\"");
76+
writeLine(" color = \"black\"");
77+
writeLine(" fillcolor = \"lightgoldenrodyellow\"");
78+
writeLine(" style = \"filled\"");
79+
writeLine(" ];");
80+
81+
// Overall edge style
82+
writeLine(" edge [");
83+
writeLine(" fontname=\"Helvetica\"");
84+
writeLine(" fontsize=\"8\"");
85+
writeLine(" fontcolor=\"black\"");
86+
writeLine(" color=\"black\"");
87+
writeLine(" arrowsize=\"0.7\"");
88+
writeLine(" ];");
89+
90+
// Write inputs as a subgraph
91+
writeInputs(workflow);
92+
93+
// Write outputs as a subgraph
94+
writeOutputs(workflow);
95+
96+
// End graph
97+
writeLine("}");
98+
}
99+
100+
/**
101+
* Writes a set of inputs from a workflow to the Writer
102+
* @param workflow The workflow to get the inputs from
103+
* @throws IOException Any errors in writing which may have occurred
104+
*/
105+
private void writeInputs(Workflow workflow) throws IOException {
106+
// Get inputs from workflow
107+
Map<String, CWLElement> inputs = workflow.getInputs();
108+
109+
// Start of subgraph with styling
110+
writeLine(" subgraph cluster_inputs {");
111+
writeLine(" rank = \"same\";");
112+
writeLine(" style = \"dashed\";");
113+
writeLine(" label = \"Workflow Inputs\";");
114+
115+
// Write each of the inputs as a node
116+
for (Map.Entry<String, CWLElement> input : workflow.getInputs().entrySet()) {
117+
writeInputOutput(input);
118+
}
119+
120+
// End subgraph
121+
writeLine(" }");
122+
}
123+
124+
/**
125+
* Writes a set of outputs from a workflow to the Writer
126+
* @param workflow The workflow to get the outputs from
127+
* @throws IOException Any errors in writing which may have occurred
128+
*/
129+
private void writeOutputs(Workflow workflow) throws IOException {
130+
// Start of subgraph with styling
131+
writeLine(" subgraph cluster_outputs {");
132+
writeLine(" rank = \"same\";");
133+
writeLine(" style = \"dashed\";");
134+
writeLine(" label = \"Workflow Outputs\";");
135+
136+
// Write each of the outputs as a node
137+
for (Map.Entry<String, CWLElement> output : workflow.getOutputs().entrySet()) {
138+
writeInputOutput(output);
139+
}
140+
141+
// End subgraph
142+
writeLine(" }");
143+
}
144+
145+
/**
146+
* Writes a single input or output to the Writer
147+
* @param inputOutput The input or output
148+
* @throws IOException Any errors in writing which may have occurred
149+
*/
150+
private void writeInputOutput(Map.Entry<String, CWLElement> inputOutput) throws IOException {
151+
// List of options for this node
152+
List<String> nodeOptions = new ArrayList<>();
153+
nodeOptions.add("fillcolor=\"#94DDF4\"");
154+
155+
// Use label if it is defined
156+
String label = inputOutput.getValue().getLabel();
157+
if (label != null && !label.isEmpty()) {
158+
nodeOptions.add("label=\"" + label + "\";");
159+
}
160+
161+
// Write the line for the node
162+
writeLine(" \"" + inputOutput.getKey() + "\" [" + String.join(",", nodeOptions) + "];");
163+
}
164+
165+
/**
166+
* Write a single line using the Writer
167+
* @param line The line to be written
168+
* @throws IOException Any errors in writing which may have occurred
169+
*/
170+
private void writeLine(String line) throws IOException {
171+
writer.write(line);
172+
writer.write(EOL);
173+
}
174+
175+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"name": "bootstrap",
3+
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
4+
"keywords": [
5+
"css",
6+
"js",
7+
"less",
8+
"mobile-first",
9+
"responsive",
10+
"front-end",
11+
"framework",
12+
"web"
13+
],
14+
"homepage": "http://getbootstrap.com",
15+
"license": "MIT",
16+
"moduleType": "globals",
17+
"main": [
18+
"less/bootstrap.less",
19+
"dist/js/bootstrap.js"
20+
],
21+
"ignore": [
22+
"/.*",
23+
"_config.yml",
24+
"CNAME",
25+
"composer.json",
26+
"CONTRIBUTING.md",
27+
"docs",
28+
"js/tests",
29+
"test-infra"
30+
],
31+
"dependencies": {
32+
"jquery": "1.9.1 - 3"
33+
},
34+
"version": "3.3.7",
35+
"_release": "3.3.7",
36+
"_resolution": {
37+
"type": "version",
38+
"tag": "v3.3.7",
39+
"commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
40+
},
41+
"_source": "https://github.com/twbs/bootstrap.git",
42+
"_target": "^3.3.7",
43+
"_originalSource": "bootstrap",
44+
"_direct": true
45+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Bootstrap uses [GitHub's Releases feature](https://github.com/blog/1547-release-your-software) for its changelogs.
2+
3+
See [the Releases section of our GitHub project](https://github.com/twbs/bootstrap/releases) for changelogs for each release version of Bootstrap.
4+
5+
Release announcement posts on [the official Bootstrap blog](http://blog.getbootstrap.com) contain summaries of the most noteworthy changes made in each release.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
source 'https://rubygems.org'
2+
3+
group :development, :test do
4+
gem 'jekyll', '~> 3.1.2'
5+
gem 'jekyll-sitemap', '~> 0.11.0'
6+
end
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
addressable (2.4.0)
5+
colorator (0.1)
6+
ffi (1.9.14-x64-mingw32)
7+
jekyll (3.1.6)
8+
colorator (~> 0.1)
9+
jekyll-sass-converter (~> 1.0)
10+
jekyll-watch (~> 1.1)
11+
kramdown (~> 1.3)
12+
liquid (~> 3.0)
13+
mercenary (~> 0.3.3)
14+
rouge (~> 1.7)
15+
safe_yaml (~> 1.0)
16+
jekyll-sass-converter (1.4.0)
17+
sass (~> 3.4)
18+
jekyll-sitemap (0.11.0)
19+
addressable (~> 2.4.0)
20+
jekyll-watch (1.4.0)
21+
listen (~> 3.0, < 3.1)
22+
kramdown (1.11.1)
23+
liquid (3.0.6)
24+
listen (3.0.8)
25+
rb-fsevent (~> 0.9, >= 0.9.4)
26+
rb-inotify (~> 0.9, >= 0.9.7)
27+
mercenary (0.3.6)
28+
rb-fsevent (0.9.7)
29+
rb-inotify (0.9.7)
30+
ffi (>= 0.5.0)
31+
rouge (1.11.1)
32+
safe_yaml (1.0.4)
33+
sass (3.4.22)
34+
35+
PLATFORMS
36+
x64-mingw32
37+
38+
DEPENDENCIES
39+
jekyll (~> 3.1.2)
40+
jekyll-sitemap (~> 0.11.0)
41+
42+
BUNDLED WITH
43+
1.12.5

0 commit comments

Comments
 (0)