com.twosigma.znai.diagrams.graphviz.gen.GraphvizFromJsonGen Maven / Gradle / Ivy
/*
* Copyright 2019 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.twosigma.znai.diagrams.graphviz.gen;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
public class GraphvizFromJsonGen {
private final Map nodesFromGraph;
private final Map nodesFromLibs;
private final List edgesFromGraph;
private final GraphvizGenConfig config;
public GraphvizFromJsonGen(Map graph, List> nodesLibraries, GraphvizGenConfig config) {
this.nodesFromGraph = extractNodesFromGraph(graph);
this.edgesFromGraph = extractEdgesFromGraph(graph);
this.nodesFromLibs = organizeNodesFromLibs(nodesLibraries);
this.config = config;
}
public GraphvizGenResult generate() {
Collection referencedNodes = findReferencedNodes();
String nodes = generateNodes(referencedNodes);
String edges = generateEdges(edgesFromGraph);
return new GraphvizGenResult("digraph Generated {\n" +
(!config.isVertical() ? "rankdir=LR;\n" : "") +
"bgcolor=\"#ffffff00\";\n" +
"node [shape=record; fontsize=10; margin=0.2; fontname=Helvetica];\n" +
(nodes.isEmpty() ? "" : "\n" + nodes + "\n") +
(edges.isEmpty() ? "" : "\n" + edges + "\n") +
"}", referencedNodes);
}
private Collection findReferencedNodes() {
Map result = new LinkedHashMap<>();
Consumer handleNodeId = (id) -> {
if (result.containsKey(id)) {
return;
}
if (nodesFromGraph.containsKey(id)) {
result.put(id, nodesFromGraph.get(id));
}
if (nodesFromLibs.containsKey(id)) {
result.put(id, nodesFromLibs.get(id));
}
};
edgesFromGraph.forEach(edge -> {
handleNodeId.accept(edge.getFromId());
handleNodeId.accept(edge.getToId());
});
return result.values();
}
@SuppressWarnings("unchecked")
private List extractEdgesFromGraph(Map graph) {
List> edges = (List>) graph.get("edges");
if (edges == null) {
throw new RuntimeException("edges are not specified");
}
return edges.stream().map(this::createEdgeFromMap).collect(toList());
}
private DiagramEdge createEdgeFromMap(List edge) {
if (edge.size() < 2 || edge.size() > 3) {
throw new IllegalArgumentException("edges definition should be in the format [from, to, optionalType]" +
" (type is either both or none)");
}
return new DiagramEdge(edge.get(0), edge.get(1), edge.size() == 3 ? edge.get(2) : "");
}
@SuppressWarnings("unchecked")
private Map extractNodesFromGraph(Map graph) {
List