package net.sourceforge.squirrel_sql.client.session.mainpanel.overview; import net.sourceforge.squirrel_sql.client.gui.mainframe.MainFrame; import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; import net.sourceforge.squirrel_sql.client.session.mainpanel.overview.datascale.DataScale; import net.sourceforge.squirrel_sql.client.session.mainpanel.overview.datascale.DataScaleListener; import net.sourceforge.squirrel_sql.client.session.mainpanel.overview.datascale.Interval; import net.sourceforge.squirrel_sql.client.session.mainpanel.overview.datascale.ScaleFactory; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import org.jfree.chart.*; import org.jfree.chart.block.*; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.title.LegendTitle; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.ui.HorizontalAlignment; import org.jfree.ui.RectangleEdge; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.HashSet; public class ChartHandler { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ChartHandler.class); public static final int MAX_LEGEND_ENTRIES = 10; public static void doChart(DataScale xAxisDataScale, DataScale yAxisDataScale, int callDepth, ChartConfigMode mode, SquirrelResources resources, Frame parent) { try { ArrayList<Object[]> rows = new ArrayList<Object[]>(); for (Interval xAxisInterval : xAxisDataScale.getIntervals()) { rows.addAll(xAxisInterval.getResultRows()); } ScaleFactory scaleFactory = new ScaleFactory(rows, xAxisDataScale.getColumnIx(), xAxisDataScale.getColumnDisplayDefinition(), callDepth); DataScaleListener dumDataScaleListener = new DataScaleListener() { @Override public void intervalSelected(Interval interval, JButton intervalButtonClicked) { } @Override public void showInTableWin(Interval interval) { } @Override public void showInTable(Interval interval) { } }; DataScale newScale = scaleFactory.createScale(dumDataScaleListener); DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset(); String category = xAxisDataScale.getColumnDisplayDefinition().getColumnName(); for (Interval interval : newScale.getIntervals()) { categoryDataset.addValue(calculateValue(interval, mode, yAxisDataScale), interval.getLabel(), category); } String title = "Chart for column: " + xAxisDataScale.getColumnDisplayDefinition().getColumnName(); JFreeChart chart = ChartFactory.createBarChart( title, // chart title category, // domain axis label mode.getYAxisLabel(yAxisDataScale), // range axis label categoryDataset, // data PlotOrientation.VERTICAL, false, // include legend true, // tooltips? false // URLs? ); JFrame f = new JFrame(title); final ImageIcon icon = resources.getIcon(SquirrelResources.IImageNames.APPLICATION_ICON); if (icon != null) { f.setIconImage(icon.getImage()); } LegendTitle legendtitle = new LegendTitle(createLegendItemSource(chart)); BlockContainer blockcontainer = new BlockContainer(new BorderArrangement()); //blockcontainer.setBorder(new BlockBorder(1.0D, 1.0D, 1.0D, 1.0D)); LabelBlock labelblock = new LabelBlock(createLabel(newScale, rows), new Font("SansSerif", 1, 12)); //labelblock.setTextAnchor(RectangleAnchor.TOP_LEFT); labelblock.setPadding(5D, 5D, 5D, 5D); blockcontainer.add(labelblock, RectangleEdge.TOP); //LabelBlock labelblock1 = new LabelBlock(createLabel(newScale, rows)); //labelblock1.setPadding(8D, 20D, 2D, 5D); //blockcontainer.add(labelblock1, RectangleEdge.BOTTOM); BlockContainer blockcontainer1 = legendtitle.getItemContainer(); blockcontainer1.setPadding(2D, 10D, 5D, 2D); blockcontainer.add(blockcontainer1); legendtitle.setWrapper(blockcontainer); legendtitle.setPosition(RectangleEdge.BOTTOM); legendtitle.setHorizontalAlignment(HorizontalAlignment.LEFT); chart.addSubtitle(legendtitle); ChartPanel chartPanel = new ChartPanel(chart); f.getContentPane().add(chartPanel); f.setLocation(parent.getLocationOnScreen()); f.setSize(parent.getSize()); f.setVisible(true); } catch (Exception e) { throw new RuntimeException(e); } } private static double calculateValue(Interval interval, ChartConfigMode mode, DataScale yAxisDataScale) { switch(mode) { case COUNT: return interval.getLen(); case SUM: double retSum = 0; for (int i = 0; i < interval.getLen(); i++) { Object o = interval.get(i); if (null != o) { retSum += ((Number) o).doubleValue(); } } return retSum; case XY_COUNT_DISTINCT: HashSet distinctSet = new HashSet(); for (int i = 0; i < interval.getLen(); i++) { int dataSetRowIndex = interval.getDataSetRowIndex(i); Object obj = yAxisDataScale.getIndexedColumn().getRow(dataSetRowIndex); distinctSet.add(obj); } return distinctSet.size(); case XY_SUM_COL: double retXYSumCol = 0; for (int i = 0; i < interval.getLen(); i++) { int dataSetRowIndex = interval.getDataSetRowIndex(i); Object obj = yAxisDataScale.getIndexedColumn().getRow(dataSetRowIndex); if (null != obj) { retXYSumCol += ((Number) obj).doubleValue(); } } return retXYSumCol; default: throw new IllegalStateException("Dont know how to handle mode: " + mode); } } private static String createLabel(DataScale dataScale, ArrayList<Object[]> rows) { String ret = "Contains " + rows.size() + " query result values in " + dataScale.getIntervals().size() + " intervals"; String intervalWidth = dataScale.getIntervalWidth(); if(null != intervalWidth) { ret += " of width " + intervalWidth; } ret += ".\nLegend shows the first and the last query result value of intervals. Intervals that contain no values are omitted."; return ret; } private static LegendItemSource createLegendItemSource(final JFreeChart chart) { return new LegendItemSource() { @Override public LegendItemCollection getLegendItems() { return reduceLegendItems(chart); } }; } private static LegendItemCollection reduceLegendItems(JFreeChart chart) { LegendItemCollection legendItems = chart.getPlot().getLegendItems(); LegendItemCollection ret = new LegendItemCollection(); for (int i = 0; i < legendItems.getItemCount(); i++) { if(MAX_LEGEND_ENTRIES < i && MAX_LEGEND_ENTRIES < legendItems.getItemCount()) { ret.add(new LegendItem("...")); ret.add(legendItems.get(legendItems.getItemCount() - 1)); break; } ret.add(legendItems.get(i)); } return ret; } }