I have an XML file and I want to create a graph based on some entities, then store this graph in an image, JPG or PNG.
So is there a library in Java to do something like this? Or are there some tricks by parsing XML files?
Here an example XML file:
<?xml version="1.0"?>
<process>
<p n="1">Tove</p>
<p n="2">Jani</p>
<p n="2">Bill</p>
<p n="4">John</p>
</process>
And the output will be like this:
You can extract the names using one of the myriad of Java XML libraries. Here's an example using XPath from a Java DOM:
private static List<String> findNames(Document doc)
throws XPathExpressionException {
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("/process/p", doc,
XPathConstants.NODESET);
List<String> names = new ArrayList<String>();
for (int i = 0; i < nodes.getLength(); i++) {
names.add(nodes.item(i).getTextContent());
}
return names;
}
Note: it may be a typo, but your XML is not well formed - attribute values must be quoted. XML parsing will fail otherwise.
You can use the AWT API to draw whatever you want:
private static final int BORDER = 1;
private static final int PADDING = 2;
private static final int SPACER = 5;
private static void draw(Graphics2D g, List<String> names) {
FontMetrics metrics = g.getFontMetrics();
Rectangle box = new Rectangle(1, 1, 0, 0);
box.height = metrics.getHeight() + (PADDING * 2);
g.setColor(Color.WHITE);
for (String name : names) {
box.width = metrics.stringWidth(name) + (PADDING * 2);
g.drawString(name, box.x + BORDER + PADDING, PADDING + BORDER +
metrics.getHeight());
g.drawRect(box.x, box.y, box.width, box.height);
box.x += box.width + (BORDER * 2) + SPACER;
}
}
This code just draws the names with some boxes around them. I'm sure my offsets are all over the place, but you probably get the idea.
There is an imageio API that can save in a few popular data formats:
private static void save(List<String> names, File file) throws IOException {
BufferedImage image = new BufferedImage(600, 50, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
try {
draw(g, names);
} finally {
g.dispose();
}
ImageIO.write(image, "png", file);
}
I'd parse the XML and output a Graphviz DOT representation like this:
digraph {
Tove -> Jani
Jani -> Bill
Bill -> John
}
Then I'd call the Graphviz dot executable from Java using ProcessRunner:
dot -Tpng -o file.png file.dot
See http://graphviz.org for further info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With