/******************************************************************************* * Copyright 2012 University of Southern California * * 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. * * This code was developed by the Information Integration Group as part * of the Karma project at the Information Sciences Institute of the * University of Southern California. For more information, publications, * and related projects, please see: http://www.isi.edu/integration ******************************************************************************/ package edu.isi.karma.modeling.research; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; import java.text.DecimalFormat; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.jgrapht.alg.DijkstraShortestPath; import org.jgrapht.graph.DirectedWeightedMultigraph; import edu.isi.karma.rep.alignment.ColumnNode; import edu.isi.karma.rep.alignment.Link; import edu.isi.karma.rep.alignment.LiteralNode; import edu.isi.karma.rep.alignment.Node; public class GraphVizUtil { public static org.kohsuke.graphviz.Graph exportJGrapPathToGraphviz(DijkstraShortestPath<Node, Link> path) { org.kohsuke.graphviz.Graph gViz = new org.kohsuke.graphviz.Graph(); if (path == null) return gViz; org.kohsuke.graphviz.Style internalNodeStyle = new org.kohsuke.graphviz.Style(); // internalNodeStyle.attr("shape", "circle"); internalNodeStyle.attr("style", "filled"); internalNodeStyle.attr("color", "white"); internalNodeStyle.attr("fontsize", "10"); internalNodeStyle.attr("fillcolor", "lightgray"); // org.kohsuke.graphviz.Style inputNodeStyle = new org.kohsuke.graphviz.Style(); // inputNodeStyle.attr("shape", "plaintext"); // inputNodeStyle.attr("style", "filled"); // inputNodeStyle.attr("fillcolor", "#3CB371"); // // org.kohsuke.graphviz.Style outputNodeStyle = new org.kohsuke.graphviz.Style(); // outputNodeStyle.attr("shape", "plaintext"); // outputNodeStyle.attr("style", "filled"); // outputNodeStyle.attr("fillcolor", "gold"); org.kohsuke.graphviz.Style parameterNodeStyle = new org.kohsuke.graphviz.Style(); parameterNodeStyle.attr("shape", "plaintext"); parameterNodeStyle.attr("style", "filled"); parameterNodeStyle.attr("fillcolor", "gold"); org.kohsuke.graphviz.Style literalNodeStyle = new org.kohsuke.graphviz.Style(); literalNodeStyle.attr("shape", "plaintext"); literalNodeStyle.attr("style", "filled"); literalNodeStyle.attr("fillcolor", "#CC7799"); org.kohsuke.graphviz.Style edgeStyle = new org.kohsuke.graphviz.Style(); edgeStyle.attr("color", "brown"); edgeStyle.attr("fontsize", "10"); edgeStyle.attr("fontcolor", "black"); HashMap<Node, org.kohsuke.graphviz.Node> nodeIndex = new HashMap<Node, org.kohsuke.graphviz.Node>(); // Node lastNode = null; for (int i = 0; i < path.getPathEdgeList().size(); i++) { Link e = path.getPathEdgeList().get(i); Node source = e.getSource(); Node target = e.getTarget(); org.kohsuke.graphviz.Node n = nodeIndex.get(source); String id = source.getId(); String uri = source.getLabel().getUri(); if (n == null) { n = new org.kohsuke.graphviz.Node(); n.attr("label", (uri == null || uri.trim().length() == 0?id:uri)); nodeIndex.put(source, n); // if (id.indexOf("att") != -1 && id.indexOf("i") != -1) // input // gViz.nodeWith(inputNodeStyle); // else if (id.indexOf("att") != -1 && id.indexOf("o") != -1) // output // gViz.nodeWith(outputNodeStyle); if (source instanceof ColumnNode) // attribute gViz.nodeWith(parameterNodeStyle); else if (source instanceof LiteralNode) // literal gViz.nodeWith(literalNodeStyle); else // internal node gViz.nodeWith(internalNodeStyle); gViz.node(n); } n = nodeIndex.get(target); id = target.getId(); uri = target.getLabel().getUri(); if (n == null) { n = new org.kohsuke.graphviz.Node(); n.attr("label", (uri == null || uri.trim().length() == 0?id:uri)); nodeIndex.put(target, n); // if (id.indexOf("att") != -1 && id.indexOf("i") != -1) // input // gViz.nodeWith(inputNodeStyle); // else if (id.indexOf("att") != -1 && id.indexOf("o") != -1) // output // gViz.nodeWith(outputNodeStyle); if (target instanceof ColumnNode) // attribute gViz.nodeWith(parameterNodeStyle); else if (target instanceof LiteralNode) // literal gViz.nodeWith(literalNodeStyle); else // internal node gViz.nodeWith(internalNodeStyle); gViz.node(n); } /* org.kohsuke.graphviz.Edge edge = null; if (i == 0) { edge = new org.kohsuke.graphviz.Edge(nodeIndex.get(source), nodeIndex.get(target)); lastNode = target; if (path.getPathEdgeList().size() > 1) { Link nextEdge = path.getPathEdgeList().get(1); if (source.equals(nextEdge.getSource()) || source.equals(nextEdge.getTarget())) { edge = new org.kohsuke.graphviz.Edge(nodeIndex.get(target), nodeIndex.get(source)); lastNode = source; } } } else if (target.equals(lastNode)) { edge = new org.kohsuke.graphviz.Edge(nodeIndex.get(target), nodeIndex.get(source)); lastNode = source; } else if (source.equals(lastNode)) { edge = new org.kohsuke.graphviz.Edge(nodeIndex.get(source), nodeIndex.get(target)); lastNode = target; } */ id = e.getId(); uri = e.getLabel().getUri(); org.kohsuke.graphviz.Edge edge = new org.kohsuke.graphviz.Edge(nodeIndex.get(source), nodeIndex.get(target)); edge.attr("label", (uri == null?id:uri)); gViz.edgeWith(edgeStyle); gViz.edge(edge); } return gViz; } private static double roundTwoDecimals(double d) { DecimalFormat twoDForm = new DecimalFormat("#.##"); return Double.valueOf(twoDForm.format(d)); } public static String getLocalName(String uri) { if (uri == null) return ""; String localName = uri; if (uri.contains("#") && !uri.endsWith("#")) localName = uri.substring(uri.lastIndexOf('#') + 1); else { if (uri.endsWith("/")) uri = uri.substring(0, uri.length() - 2); if (uri.contains("/")) localName = uri.substring(uri.lastIndexOf('/') + 1); } return localName; } private static String getPatterns(Set<String> patternIds) { String label = ""; if (patternIds == null || patternIds.size() == 0) return label; label += "["; for (String pId : patternIds) label += pId + ","; if (label.endsWith(",")) label = label.substring(0, label.length() - 1); label += "]"; return label; } public static org.kohsuke.graphviz.Graph exportJGraphToGraphviz(DirectedWeightedMultigraph<Node, Link> model, boolean showDescription) { org.kohsuke.graphviz.Graph gViz = new org.kohsuke.graphviz.Graph(); if (model == null) return gViz; org.kohsuke.graphviz.Style internalNodeStyle = new org.kohsuke.graphviz.Style(); // internalNodeStyle.attr("shape", "circle"); internalNodeStyle.attr("style", "filled"); internalNodeStyle.attr("color", "white"); internalNodeStyle.attr("fontsize", "10"); internalNodeStyle.attr("fillcolor", "lightgray"); // org.kohsuke.graphviz.Style inputNodeStyle = new org.kohsuke.graphviz.Style(); // inputNodeStyle.attr("shape", "plaintext"); // inputNodeStyle.attr("style", "filled"); // inputNodeStyle.attr("fillcolor", "#3CB371"); // // org.kohsuke.graphviz.Style outputNodeStyle = new org.kohsuke.graphviz.Style(); // outputNodeStyle.attr("shape", "plaintext"); // outputNodeStyle.attr("style", "filled"); // outputNodeStyle.attr("fillcolor", "gold"); org.kohsuke.graphviz.Style parameterNodeStyle = new org.kohsuke.graphviz.Style(); parameterNodeStyle.attr("shape", "plaintext"); parameterNodeStyle.attr("style", "filled"); parameterNodeStyle.attr("fillcolor", "gold"); org.kohsuke.graphviz.Style literalNodeStyle = new org.kohsuke.graphviz.Style(); literalNodeStyle.attr("shape", "plaintext"); literalNodeStyle.attr("style", "filled"); literalNodeStyle.attr("fillcolor", "#CC7799"); org.kohsuke.graphviz.Style edgeStyle = new org.kohsuke.graphviz.Style(); edgeStyle.attr("color", "brown"); edgeStyle.attr("fontsize", "10"); edgeStyle.attr("fontcolor", "black"); HashMap<Node, org.kohsuke.graphviz.Node> nodeIndex = new HashMap<Node, org.kohsuke.graphviz.Node>(); for (Link e : model.edgeSet()) { Node source = e.getSource(); Node target = e.getTarget(); org.kohsuke.graphviz.Node n = nodeIndex.get(source); String id = source.getId(); String uri = id;//source.getLabel().getUri(); String localName = getLocalName(uri); String label; if (n == null) { n = new org.kohsuke.graphviz.Node(); // label = (uri == null || uri.trim().length() == 0?id:uri)); label = (localName == null || localName.trim().length() == 0?id:localName); if (showDescription) label += " " + getPatterns(source.getPatternIds()); n.attr("label", label); nodeIndex.put(source, n); // if (id.indexOf("att") != -1 && id.indexOf("i") != -1) // input // gViz.nodeWith(inputNodeStyle); // else if (id.indexOf("att") != -1 && id.indexOf("o") != -1) // output // gViz.nodeWith(outputNodeStyle); if (source instanceof ColumnNode) // attribute gViz.nodeWith(parameterNodeStyle); else if (source instanceof LiteralNode) // literal gViz.nodeWith(literalNodeStyle); else // internal node gViz.nodeWith(internalNodeStyle); gViz.node(n); } n = nodeIndex.get(target); id = target.getId(); uri = id;//target.getLabel().getUri(); localName = getLocalName(uri); if (n == null) { n = new org.kohsuke.graphviz.Node(); // label = (uri == null || uri.trim().length() == 0?id:uri)); label = (localName == null || localName.trim().length() == 0?id:localName); if (showDescription) label += " " + getPatterns(target.getPatternIds()); n.attr("label", label); nodeIndex.put(target, n); // if (id.indexOf("att") != -1 && id.indexOf("i") != -1) // input // gViz.nodeWith(inputNodeStyle); // else if (id.indexOf("att") != -1 && id.indexOf("o") != -1) // output // gViz.nodeWith(outputNodeStyle); if (target instanceof ColumnNode) // attribute gViz.nodeWith(parameterNodeStyle); else if (target instanceof LiteralNode) // literal gViz.nodeWith(literalNodeStyle); else // internal node gViz.nodeWith(internalNodeStyle); gViz.node(n); } id = e.getId(); uri = e.getLabel().getUri(); localName = getLocalName(uri); org.kohsuke.graphviz.Edge edge = new org.kohsuke.graphviz.Edge(nodeIndex.get(source), nodeIndex.get(target)); // String label = (uri == null?id:uri); label = (localName == null?id:localName); if (showDescription) { label += "-(" + roundTwoDecimals(e.getWeight()) + ")-"; label += " "; label += getPatterns(e.getPatternIds()); } edge.attr("label", label); gViz.edgeWith(edgeStyle); gViz.edge(edge); } return gViz; } public static void exportJGraphToGraphvizFile( DirectedWeightedMultigraph<Node, Link> model, String label, String exportPath) throws FileNotFoundException { org.kohsuke.graphviz.Graph graphViz = exportJGraphToGraphviz(model, true); graphViz.attr("fontcolor", "blue"); graphViz.attr("remincross", "true"); graphViz.attr("label", label); OutputStream out = new FileOutputStream(exportPath); graphViz.writeTo(out); } public static void exportJGraphToGraphvizFile(Map<String, DirectedWeightedMultigraph<Node, Link>> models, String label, String exportPath) throws FileNotFoundException { org.kohsuke.graphviz.Graph graphViz = new org.kohsuke.graphviz.Graph(); graphViz.attr("fontcolor", "blue"); graphViz.attr("remincross", "true"); graphViz.attr("label", label); org.kohsuke.graphviz.Graph cluster = null; int counter = 0; boolean showLinkDescription; if (models != null) { for(Entry<String,DirectedWeightedMultigraph<Node, Link>> entry : models.entrySet()) { if (entry.getKey() == "1-correct model") showLinkDescription = false; else showLinkDescription = true; cluster = GraphVizUtil.exportJGraphToGraphviz(entry.getValue(), showLinkDescription); cluster.id("cluster_" + counter); cluster.attr("label", entry.getKey()); graphViz.subGraph(cluster); counter++; } } OutputStream out = new FileOutputStream(exportPath); graphViz.writeTo(out); } }