This page shows how to generate JFreeChart based charts from Wicket that displays tooltips.
Tooltips are very important, especially in charts like line charts, time-series charts etc. Showing tooltips in images embedded in html pages is achieved by making use of html "map". Fortunately, JFreeChart has built-in support for generating the map details for the images. This example basically takes the concepts mentioned in the article JFreeChart and wicket example and tweaks it a little to add the "map" information so that we can display tooltips.
Let us see a simple time series chart example that attempts to realize the concepts mentioned above.
TimeSeriesChartExamplePage.html
...
Code Block |
---|
public final class TimeSeriesChartExamplePage extends WebPage
{
public TimeSeriesChartExamplePage()
{
super();
add(createChartImage());
}
private Image createChartImage()
{
return new JFreeChartImageWithToolTip("chart", getChartModel(), "tooltip", 800, 400);
}
private IModel<JFreeChart> getChartModel()
{
return new LoadableDetachableModel<JFreeChart>()
{
@Override
protected JFreeChart load()
{
return createTimeSeriesChart();
}
};
}
private JFreeChart createTimeSeriesChart()
{
//create a chart based on a dummy time series dataset
TimeSeries timeSeries = new TimeSeries("Page hits", Month.class);
for (int i = 1; i <= 10; i++) {
timeSeries.add(new Month(i, 2010), (i * 1000));
}
TimeSeriesCollection dataSet = new TimeSeriesCollection(timeSeries);
JFreeChart chart = ChartFactory.createTimeSeriesChart("Page hits in a month", "Months",
"Page hits", dataSet, false, true, false);
//set some chart attributes
return applyChartAttributes(chart);
}
private JFreeChart applyChartAttributes(JFreeChart chart)
{
XYPlot plot = (XYPlot) chart.getPlot();
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setBaseShapesVisible(true);
renderer.setBaseShapesFilled(true);
renderer.setSeriesPaint(0, Color.BLUE);
}
return chart;
}
|
JFreeChartImageWithToolTip.java
NOTE: This class was taken from the http://markmail.org/message/r36cvdt2o3c4pki6#query:wicket%20jfreechart%20tooltips+page:1+mid:xqpnjdsj2lnkoinq+state:results (Taken from the mailing list archive with minor changes to make use of wicket models.)
Code Block |
---|
public class JFreeChartImageWithToolTip extends NonCachingImage { private static final Logger logger = LoggerFactory.getLogger(JFreeChartImageWithToolTip.class); private String imageMapId; private int width; private int height; private ChartRenderingInfo chartRenderingInfo = new ChartRenderingInfo(new StandardEntityCollection()); public JFreeChartImageWithToolTip(String id, IModel<JFreeChart> model, String imageMapId, int width, int height) { super(id, model); this.imageMapId = imageMapId; this.width = width; this.height = height; } @Override protected Resource getImageResource() { Resource imageResource = null; final JFreeChart chart = (JFreeChart) getDefaultModelObject(); imageResource = new DynamicImageResource() { @Override protected byte[] getImageData() { ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { if (chart != null) { chartRenderingInfo.clear(); ChartUtilities.writeChartAsPNG(stream, chart, width, height, chartRenderingInfo); } } catch (IOException ex) { logger.error("Error occured while creating chart", ex); } return stream.toByteArray(); } }; return imageResource; } @Override protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) { JFreeChart chart = (JFreeChart) getDefaultModelObject(); if (chart == null) { return; } ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { if (chart != null) { chartRenderingInfo.clear(); ChartUtilities.writeChartAsPNG(stream, chart, width, height, chartRenderingInfo); } } catch (IOException ex) { logger.error("Error occured while creating chart", ex); } replaceComponentTagBody(markupStream, openTag, ChartUtilities.getImageMap(imageMapId, chartRenderingInfo)); } |
Result
Resulting html
Code Block |
---|
<html>
<body>
<img wicket:id="chart" usemap="#tooltip" src="?wicket:interface=:3:chart::IResourceListener::&wicket:antiCache=1286158256270">
<map id="tooltip" name="tooltip">
<area shape="poly" coords="775,39,781,39,781,45,775,45,775,39,775,39" title="Page hits: (10/1/10 12:00 AM, 10,000)" alt="" nohref="nohref">
<area shape="poly" coords="698,72,704,72,704,78,698,78,698,72,698,72" title="Page hits: (9/1/10 12:00 AM, 9,000)" alt="" nohref="nohref">
<area shape="poly" coords="619,106,625,106,625,112,619,112,619,106,619,106" title="Page hits: (8/1/10 12:00 AM, 8,000)" alt="" nohref="nohref">
<area shape="poly" coords="540,140,546,140,546,146,540,146,540,140,540,140" title="Page hits: (7/1/10 12:00 AM, 7,000)" alt="" nohref="nohref">
<area shape="poly" coords="464,173,470,173,470,179,464,179,464,173,464,173" title="Page hits: (6/1/10 12:00 AM, 6,000)" alt="" nohref="nohref">
<area shape="poly" coords="385,207,391,207,391,213,385,213,385,207,385,207" title="Page hits: (5/1/10 12:00 AM, 5,000)" alt="" nohref="nohref">
<area shape="poly" coords="309,241,315,241,315,247,309,247,309,241,309,241" title="Page hits: (4/1/10 12:00 AM, 4,000)" alt="" nohref="nohref">
<area shape="poly" coords="230,274,236,274,236,280,230,280,230,274,230,274" title="Page hits: (3/1/10 12:00 AM, 3,000)" alt="" nohref="nohref">
<area shape="poly" coords="158,308,164,308,164,314,158,314,158,308,158,308" title="Page hits: (2/1/10 12:00 AM, 2,000)" alt="" nohref="nohref">
<area shape="poly" coords="79,342,85,342,85,348,79,348,79,342,79,342" title="Page hits: (1/1/10 12:00 AM, 1,000)" alt="" nohref="nohref">
</map>
</body>
</html>
|
Pitfalls to avoid:
- You must use
and notCode Block <img wicket:id="chart" usemap="#tooltip"></img>
Code Block <img wicket:id="chart" usemap="#tooltip"/>
- Do not forget to use the "#" symbol before the "map" id.
Resources & References