Macca Blog

My life experiences with code and design

JavaFX Graphing and Charting with Hudson pt 2

Posted on by Mark

In my last post on building some bar charts with the data gathered from the Hudson REST api, http://markmacumber.blogspot.com/2009/07/javafx-graphing-and-charting-with.html.

In this article I would like to extend the basic functionality of that graph and also highlight broken builds with RED bars.

The basic idea behind this small enhancement, is to structure the XML parsing in a more efficient manor and clean up some of the code.

I also wanted to add a floating dialog over each bar to show details of the build (which you could easily extend to add more details).

I will be using the EXACT same Java code to access the XML from Hudson, as posted in the previous blog entry.

Here is the source code:

package hudsongraphs;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.part.CategoryAxis;
import javafx.scene.chart.part.NumberAxis;
import javafx.scene.text.Font;
import javafx.scene.paint.Color;

import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;

import hudsonremoteaccess.Hudson;

import org.dom4j.Document;
import org.dom4j.tree.DefaultElement;

/**
* Hudson Graphing:
* Sample JavaFX application that will make a remote call to the Hudson
* API's, parse the XML and generate a nice bar-graph of build information.
* @author Mark Macumber
*/
var hudson:Hudson = new Hudson();

var xmlDoc:Document = hudson.getXMLHudsonQuery();
var builds = xmlDoc.selectNodes("//build");

var numbers:String[] = [];

//the actual bar char data
var barChartData:BarChart.Data[];

var currentMouseX:Number = 0;
var currentMouseY:Number = 0;

//Text that will float in the dialog
var buildText:Text = Text {
font : Font { size: 12 }
x: bind currentMouseX + 12,
y: bind currentMouseY + 20
};

//floating rectangle that will follow the mouse on each build
var floatingRect:Rectangle = Rectangle{
width: 120
height: 50
arcHeight: 5
arcWidth: 5
fill: Color.WHITESMOKE
stroke: Color.BLACK
x: bind currentMouseX
y: bind currentMouseY
visible: false
};

for (build in builds) {
var idx = indexof build;
var bDuration = getElement(build as DefaultElement, "duration");
var durationInMilliseconds = Number.valueOf(bDuration);
var durationInMinutes = ((durationInMilliseconds/1000)/60);

var bNumber = getElement(build as DefaultElement, "number");
var bResult = getElement(build as DefaultElement, "result");
var bDisplayName = getElement(build as DefaultElement, "fullDisplayName");

insert bNumber into numbers;

var barChart:BarChart.Data =
BarChart.Data {
category: bNumber
value: durationInMinutes
};

var chartNode = Rectangle{
onMouseMoved: function( e: MouseEvent ):Void {
currentMouseX = e.sceneX + 15;
currentMouseY = e.sceneY + 5;
floatingRect.visible = true;
buildText.content = "{bDisplayName}\nDuration: {durationInMinutes as Integer}mins";
}
x: 0
y: 0
width: bind barChart.width
height: bind barChart.height
fill: if (bResult == "SUCCESS") Color.GREEN else Color.RED;
};

barChart.bar = chartNode;
insert barChart into barChartData;
}

function getElement(element:DefaultElement, xpath:String):String{
(element.selectNodes(xpath).get(0) as DefaultElement).getData() as String;
}

Stage {
title: "Hudson Build Duration Timeline"
width: 800
height: 450
scene: Scene {
content: [
BarChart {
title: "Hudson Build Duration Timeline"
width: 750
titleFont: Font { size: 24 }
categoryGap: 2
categoryAxis: CategoryAxis {
categories: numbers
}
valueAxis: NumberAxis {
label: "Build Duration (minutes)"
upperBound: 500
tickUnit: 100
}
data: [
BarChart.Series {
name: "Build #'s"
fill: Color.GREEN
data: barChartData
}
]
},
floatingRect,
buildText
]
}
}

As you can see, the code is actually pretty strait forward, and the enhancements has been mainly around how to parse the XML, and create the floating box, which, I have to admit, was a fair amount of trial an error :)

Here is a screen shot:

The full source code is available via the JFXtras project, in which this sample has been checked in for all to see and use in the “samples” project.

You will find it under the MarkMacumberFX\HudsonGraphs

There is also an article published on the JFXtras.org samples page that contains all the links you will need to run the JNLP file, etc…

I will be hoping to continually update this code and make more and more graphs, to enhance the Hudson reporting, and hopefully getting some kind of real integration with Hudson.

Here is a direct link to the JNLP file:

Enjoy
Mark!

This entry was posted in Charting, Graphing, Hudson, Java, JavaFX. Bookmark the permalink.

Leave a Comment

Your email address will not be published. Required fields are marked *


*