IDEMPIERE-1583 Zk: Pluggable Chart Renderer Service.
This commit is contained in:
parent
69ca16cbd9
commit
a7db58fb5b
|
@ -0,0 +1,642 @@
|
|||
/******************************************************************************
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.apps.graph;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.DBException;
|
||||
import org.compiere.model.MChart;
|
||||
import org.compiere.model.MChartDatasource;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.model.MRole;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.model.X_AD_Chart;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.CategoryAxis;
|
||||
import org.jfree.chart.axis.CategoryLabelPositions;
|
||||
import org.jfree.chart.plot.CategoryPlot;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.renderer.category.BarRenderer;
|
||||
import org.jfree.chart.renderer.category.CategoryItemRenderer;
|
||||
import org.jfree.chart.renderer.category.StandardBarPainter;
|
||||
import org.jfree.data.category.CategoryDataset;
|
||||
import org.jfree.data.category.DefaultCategoryDataset;
|
||||
import org.jfree.data.general.Dataset;
|
||||
import org.jfree.data.general.DefaultPieDataset;
|
||||
import org.jfree.data.general.PieDataset;
|
||||
import org.jfree.data.time.Day;
|
||||
import org.jfree.data.time.Month;
|
||||
import org.jfree.data.time.Quarter;
|
||||
import org.jfree.data.time.RegularTimePeriod;
|
||||
import org.jfree.data.time.TimeSeries;
|
||||
import org.jfree.data.time.TimeSeriesCollection;
|
||||
import org.jfree.data.time.Week;
|
||||
import org.jfree.data.time.Year;
|
||||
import org.jfree.data.xy.IntervalXYDataset;
|
||||
|
||||
/**
|
||||
* @author Paul Bowden, Adaxa Pty Ltd
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class ChartBuilder {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(ChartBuilder.class);
|
||||
|
||||
private MChart chartModel;
|
||||
private HashMap<String,MQuery> queries;
|
||||
private Dataset dataset;
|
||||
|
||||
public ChartBuilder(MChart chart) {
|
||||
this.chartModel = chart;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @return JFreeChart
|
||||
*/
|
||||
public JFreeChart createChart() {
|
||||
|
||||
String type = chartModel.getChartType();
|
||||
|
||||
if(MChart.CHARTTYPE_BarChart.equals(type))
|
||||
{
|
||||
if ( chartModel.isTimeSeries())
|
||||
{
|
||||
return createXYBarChart();
|
||||
}
|
||||
return createBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DBarChart.equals(type))
|
||||
{
|
||||
return create3DBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_StackedBarChart.equals(type))
|
||||
{
|
||||
|
||||
if ( chartModel.isTimeSeries())
|
||||
return createXYBarChart();
|
||||
|
||||
return createStackedBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DStackedBarChart.equals(type))
|
||||
{
|
||||
return create3DStackedBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DPieChart.equals(type))
|
||||
{
|
||||
return create3DPieChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_PieChart.equals(type))
|
||||
{
|
||||
return createPieChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DLineChart.equals(type))
|
||||
{
|
||||
return create3DLineChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_AreaChart.equals(type))
|
||||
{
|
||||
return createAreaChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_StackedAreaChart.equals(type))
|
||||
{
|
||||
return createStackedAreaChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_LineChart.equals(type))
|
||||
{
|
||||
if ( chartModel.isTimeSeries() )
|
||||
return createTimeSeriesChart();
|
||||
return createLineChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_RingChart.equals(type))
|
||||
{
|
||||
return createRingChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_WaterfallChart.equals(type))
|
||||
{
|
||||
return createWaterfallChart();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("unknown chart type=" + type);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadData() {
|
||||
queries = new HashMap<String,MQuery>();
|
||||
for ( MChartDatasource ds : chartModel.getDatasources() )
|
||||
{
|
||||
addData(ds);
|
||||
}
|
||||
}
|
||||
|
||||
private void addData(MChartDatasource ds) {
|
||||
|
||||
String value = ds.getValueColumn();
|
||||
String category;
|
||||
String unit = "D";
|
||||
|
||||
if ( !chartModel.isTimeSeries() )
|
||||
category = ds.getCategoryColumn();
|
||||
else
|
||||
{
|
||||
if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Week))
|
||||
{
|
||||
unit = "W";
|
||||
}
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Month))
|
||||
{
|
||||
unit = "MM";
|
||||
}
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Quarter))
|
||||
{
|
||||
unit = "Q";
|
||||
}
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Year))
|
||||
{
|
||||
unit = "Y";
|
||||
}
|
||||
|
||||
category = " TRUNC(" + ds.getDateColumn() + ", '" + unit + "') ";
|
||||
}
|
||||
|
||||
String series = DB.TO_STRING(ds.getName());
|
||||
boolean hasSeries = false;
|
||||
if (ds.getSeriesColumn() != null)
|
||||
{
|
||||
series = ds.getSeriesColumn();
|
||||
hasSeries = true;
|
||||
}
|
||||
|
||||
String where = ds.getWhereClause();
|
||||
if ( !Util.isEmpty(where))
|
||||
{
|
||||
where = Env.parseContext(Env.getCtx(), chartModel.getWindowNo(), where, true);
|
||||
}
|
||||
|
||||
boolean hasWhere = false;
|
||||
|
||||
String sql = "SELECT " + value + ", " + category + ", " + series
|
||||
+ " FROM " + ds.getFromClause();
|
||||
if ( !Util.isEmpty(where))
|
||||
{
|
||||
sql += " WHERE " + where;
|
||||
hasWhere = true;
|
||||
}
|
||||
|
||||
Date currentDate = Env.getContextAsDate(Env.getCtx(), "#Date");
|
||||
Date startDate = null;
|
||||
Date endDate = null;
|
||||
|
||||
int scope = chartModel.getTimeScope();
|
||||
int offset = ds.getTimeOffset();
|
||||
|
||||
if ( chartModel.isTimeSeries() && scope != 0 )
|
||||
{
|
||||
offset += -scope;
|
||||
startDate = increment(currentDate, chartModel.getTimeUnit(), offset);
|
||||
endDate = increment(startDate, chartModel.getTimeUnit(), scope);
|
||||
}
|
||||
|
||||
if ( startDate != null && endDate != null )
|
||||
{
|
||||
sql += hasWhere ? " AND " : " WHERE ";
|
||||
sql += category + ">=TRUNC(" + DB.TO_DATE(new Timestamp(startDate.getTime())) + ", '" + unit + "') AND ";
|
||||
sql += category + "<=TRUNC(" + DB.TO_DATE(new Timestamp(endDate.getTime())) + ", '" + unit + "') ";
|
||||
}
|
||||
|
||||
if (sql.indexOf('@') >= 0) {
|
||||
sql = Env.parseContext(Env.getCtx(), 0, sql, false, true);
|
||||
}
|
||||
|
||||
MRole role = MRole.getDefault(Env.getCtx(), false);
|
||||
sql = role.addAccessSQL(sql, null, true, false);
|
||||
|
||||
if (hasSeries)
|
||||
sql += " GROUP BY " + series + ", " + category + " ORDER BY " + series + ", " + category;
|
||||
else
|
||||
sql += " GROUP BY " + category + " ORDER BY " + category;
|
||||
|
||||
log.log(Level.FINE, sql);
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
TimeSeries tseries = null;
|
||||
Dataset dataset = getDataset();
|
||||
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
rs = pstmt.executeQuery();
|
||||
while(rs.next())
|
||||
{
|
||||
|
||||
String key = rs.getString(2);
|
||||
String seriesName = rs.getString(3);
|
||||
if (seriesName == null)
|
||||
seriesName = ds.getName();
|
||||
String queryWhere = "";
|
||||
if ( hasWhere )
|
||||
queryWhere += where + " AND ";
|
||||
|
||||
queryWhere += series + " = " + DB.TO_STRING(seriesName) + " AND " + category + " = " ;
|
||||
|
||||
if ( chartModel.isTimeSeries() && dataset instanceof TimeSeriesCollection )
|
||||
{
|
||||
|
||||
if ( tseries == null || !tseries.getKey().equals(seriesName))
|
||||
{
|
||||
if (tseries != null)
|
||||
((TimeSeriesCollection) dataset).addSeries(tseries);
|
||||
|
||||
tseries = new TimeSeries(seriesName);
|
||||
}
|
||||
|
||||
Date date = rs.getDate(2);
|
||||
RegularTimePeriod period = null;
|
||||
|
||||
if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Day))
|
||||
period = new Day(date);
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Week))
|
||||
period = new Week(date);
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Month))
|
||||
period = new Month(date);
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Quarter))
|
||||
period = new Quarter(date);
|
||||
else if ( chartModel.getTimeUnit().equals(MChart.TIMEUNIT_Year))
|
||||
period = new Year(date);
|
||||
|
||||
tseries.add(period, rs.getBigDecimal(1));
|
||||
key = period.toString();
|
||||
queryWhere += DB.TO_DATE(new Timestamp(date.getTime()));
|
||||
}
|
||||
else {
|
||||
queryWhere += DB.TO_STRING(key);
|
||||
}
|
||||
|
||||
MQuery query = new MQuery(ds.getAD_Table_ID());
|
||||
String keyCol = MTable.get(Env.getCtx(), ds.getAD_Table_ID()).getKeyColumns()[0];
|
||||
String whereClause = keyCol + " IN (SELECT " + ds.getKeyColumn() + " FROM "
|
||||
+ ds.getFromClause() + " WHERE " + queryWhere + " )";
|
||||
query.addRestriction(whereClause.toString());
|
||||
query.setRecordCount(1);
|
||||
|
||||
HashMap<String, MQuery> map = getQueries();
|
||||
|
||||
if ( dataset instanceof DefaultPieDataset) {
|
||||
((DefaultPieDataset) dataset).setValue(key, rs.getBigDecimal(1));
|
||||
map.put(key, query);
|
||||
}
|
||||
else if ( dataset instanceof DefaultCategoryDataset ) {
|
||||
((DefaultCategoryDataset) dataset).addValue(rs.getBigDecimal(1), seriesName, key);
|
||||
map.put(seriesName + "__" + key, query);
|
||||
}
|
||||
else if (dataset instanceof TimeSeriesCollection )
|
||||
{
|
||||
map.put(seriesName + "__" + key, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new DBException(e, sql);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
|
||||
if (tseries != null)
|
||||
((TimeSeriesCollection) dataset).addSeries(tseries);
|
||||
|
||||
}
|
||||
|
||||
private Date increment(Date lastDate, String timeUnit, int qty) {
|
||||
|
||||
if ( lastDate == null )
|
||||
return null;
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(lastDate);
|
||||
|
||||
if ( timeUnit.equals(MChart.TIMEUNIT_Day))
|
||||
cal.add(Calendar.DAY_OF_YEAR, qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Week))
|
||||
cal.add(Calendar.WEEK_OF_YEAR, qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Month))
|
||||
cal.add(Calendar.MONTH, qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Quarter))
|
||||
cal.add(Calendar.MONTH, 3*qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Year))
|
||||
cal.add(Calendar.YEAR, qty);
|
||||
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public CategoryDataset getCategoryDataset() {
|
||||
dataset = new DefaultCategoryDataset();
|
||||
loadData();
|
||||
return (CategoryDataset) dataset;
|
||||
}
|
||||
|
||||
public IntervalXYDataset getXYDataset() {
|
||||
dataset = new TimeSeriesCollection();
|
||||
loadData();
|
||||
return (IntervalXYDataset) dataset;
|
||||
}
|
||||
|
||||
public PieDataset getPieDataset() {
|
||||
dataset = new DefaultPieDataset();
|
||||
loadData();
|
||||
return (PieDataset) dataset;
|
||||
}
|
||||
|
||||
public Dataset getDataset() {
|
||||
return dataset;
|
||||
}
|
||||
|
||||
public HashMap<String, MQuery> getQueries() {
|
||||
return queries;
|
||||
}
|
||||
|
||||
public MQuery getQuery(String key) {
|
||||
|
||||
|
||||
if ( queries.containsKey(key) )
|
||||
{
|
||||
return queries.get(key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private JFreeChart createXYBarChart() {
|
||||
JFreeChart chart = ChartFactory.createXYBarChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
true,
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getXYDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createTimeSeriesChart() {
|
||||
JFreeChart chart = ChartFactory.createTimeSeriesChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getXYDataset(), // data
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createWaterfallChart() {
|
||||
JFreeChart chart = ChartFactory.createWaterfallChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createRingChart() {
|
||||
final JFreeChart chart = ChartFactory.createRingChart(chartModel.getName(),
|
||||
getPieDataset(), chartModel.isDisplayLegend(), true, true);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createPieChart() {
|
||||
final JFreeChart chart = ChartFactory.createPieChart(chartModel.getName(),
|
||||
getPieDataset(), false, true, true);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DPieChart() {
|
||||
final JFreeChart chart = ChartFactory.createPieChart3D(chartModel.getName(),
|
||||
getPieDataset(), false, true, true);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createBarChart() {
|
||||
JFreeChart chart = ChartFactory.createBarChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
BarRenderer renderer = new BarRenderer();
|
||||
renderer.setBarPainter(new StandardBarPainter());
|
||||
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
plot.setRenderer(renderer);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DBarChart() {
|
||||
JFreeChart chart = ChartFactory.createBarChart3D(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createStackedBarChart() {
|
||||
JFreeChart chart = ChartFactory.createStackedBarChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
BarRenderer renderer = new BarRenderer();
|
||||
renderer.setBarPainter(new StandardBarPainter());
|
||||
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
plot.setRenderer(renderer);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DStackedBarChart() {
|
||||
JFreeChart chart = ChartFactory.createStackedBarChart3D(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createAreaChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createAreaChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createStackedAreaChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createStackedAreaChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createLineChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createLineChart(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DLineChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createLineChart3D(
|
||||
chartModel.getName(), // chart title
|
||||
chartModel.getDomainLabel(), // domain axis label
|
||||
chartModel.getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(chartModel.getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
chartModel.isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private void setupCategoryChart(JFreeChart chart) {
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
CategoryAxis xAxis = (CategoryAxis)plot.getDomainAxis();
|
||||
xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
|
||||
|
||||
CategoryItemRenderer renderer = plot.getRenderer();
|
||||
renderer.setSeriesPaint(0, Color.RED);
|
||||
renderer.setSeriesPaint(1, Color.BLUE);
|
||||
renderer.setSeriesPaint(2, Color.YELLOW);
|
||||
renderer.setSeriesPaint(3, Color.GREEN);
|
||||
renderer.setSeriesPaint(4, Color.ORANGE);
|
||||
renderer.setSeriesPaint(5, Color.CYAN);
|
||||
renderer.setSeriesPaint(6, Color.MAGENTA);
|
||||
renderer.setSeriesPaint(7, Color.GRAY);
|
||||
renderer.setSeriesPaint(8, Color.PINK);
|
||||
|
||||
plot.setRenderer(renderer);
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ package org.adempiere.apps.graph;
|
|||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.compiere.model.MGoal;
|
||||
import org.compiere.model.MMeasure;
|
||||
|
@ -245,6 +246,11 @@ public class GraphBuilder {
|
|||
|
||||
ArrayList<GraphColumn>list = measure.getGraphColumnList(getMGoal());
|
||||
|
||||
loadDataSet(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
public void loadDataSet(List<GraphColumn> list) {
|
||||
pieDataset = new DefaultPieDataset();
|
||||
dataset = new DefaultCategoryDataset();
|
||||
for (int i = 0; i < list.size(); i++){
|
||||
|
@ -260,6 +266,5 @@ public class GraphBuilder {
|
|||
list.get(i).getLabel());
|
||||
pieDataset.setValue(list.get(i).getLabel(), list.get(i).getValue());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -1,27 +1,10 @@
|
|||
package org.compiere.model;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.CategoryAxis;
|
||||
import org.jfree.chart.axis.CategoryLabelPositions;
|
||||
import org.jfree.chart.plot.CategoryPlot;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.renderer.category.BarRenderer;
|
||||
import org.jfree.chart.renderer.category.CategoryItemRenderer;
|
||||
import org.jfree.chart.renderer.category.StandardBarPainter;
|
||||
import org.jfree.data.category.CategoryDataset;
|
||||
import org.jfree.data.category.DefaultCategoryDataset;
|
||||
import org.jfree.data.general.Dataset;
|
||||
import org.jfree.data.general.DefaultPieDataset;
|
||||
import org.jfree.data.general.PieDataset;
|
||||
import org.jfree.data.time.TimeSeriesCollection;
|
||||
import org.jfree.data.xy.IntervalXYDataset;
|
||||
|
||||
|
||||
public class MChart extends X_AD_Chart {
|
||||
|
||||
|
@ -31,8 +14,6 @@ public class MChart extends X_AD_Chart {
|
|||
private static final long serialVersionUID = -8851465915516536910L;
|
||||
|
||||
private int windowNo=0;
|
||||
private Dataset dataset;
|
||||
private HashMap<String,MQuery> queries;
|
||||
|
||||
public MChart(Properties ctx, int AD_Chart_ID, String trxName) {
|
||||
super(ctx, AD_Chart_ID, trxName);
|
||||
|
@ -42,46 +23,12 @@ public class MChart extends X_AD_Chart {
|
|||
super(ctx, rs, trxName);
|
||||
}
|
||||
|
||||
public void loadData() {
|
||||
queries = new HashMap<String,MQuery>();
|
||||
for ( MChartDatasource ds : getDatasources() )
|
||||
{
|
||||
ds.addData(this);
|
||||
}
|
||||
}
|
||||
|
||||
public CategoryDataset getCategoryDataset() {
|
||||
dataset = new DefaultCategoryDataset();
|
||||
loadData();
|
||||
return (CategoryDataset) dataset;
|
||||
}
|
||||
|
||||
public IntervalXYDataset getXYDataset() {
|
||||
dataset = new TimeSeriesCollection();
|
||||
loadData();
|
||||
return (IntervalXYDataset) dataset;
|
||||
}
|
||||
|
||||
public PieDataset getPieDataset() {
|
||||
dataset = new DefaultPieDataset();
|
||||
loadData();
|
||||
return (PieDataset) dataset;
|
||||
}
|
||||
|
||||
public Dataset getDataset() {
|
||||
return dataset;
|
||||
}
|
||||
|
||||
private List<MChartDatasource> getDatasources() {
|
||||
public List<MChartDatasource> getDatasources() {
|
||||
|
||||
return new Query(getCtx(), MChartDatasource.Table_Name, MChart.COLUMNNAME_AD_Chart_ID + "=?", null)
|
||||
.setParameters(getAD_Chart_ID()).setOnlyActiveRecords(true).list();
|
||||
}
|
||||
|
||||
public HashMap<String, MQuery> getQueries() {
|
||||
return queries;
|
||||
}
|
||||
|
||||
public void setWindowNo(int windowNo) {
|
||||
this.windowNo = windowNo;
|
||||
}
|
||||
|
@ -89,334 +36,4 @@ public class MChart extends X_AD_Chart {
|
|||
public int getWindowNo() {
|
||||
return windowNo;
|
||||
}
|
||||
|
||||
public MQuery getQuery(String key) {
|
||||
|
||||
|
||||
if ( queries.containsKey(key) )
|
||||
{
|
||||
return queries.get(key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @return JFreeChart
|
||||
*/
|
||||
public JFreeChart createChart() {
|
||||
|
||||
String type = getChartType();
|
||||
|
||||
if(MChart.CHARTTYPE_BarChart.equals(type))
|
||||
{
|
||||
if ( isTimeSeries())
|
||||
{
|
||||
return createXYBarChart();
|
||||
}
|
||||
return createBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DBarChart.equals(type))
|
||||
{
|
||||
return create3DBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_StackedBarChart.equals(type))
|
||||
{
|
||||
|
||||
if ( isTimeSeries())
|
||||
return createXYBarChart();
|
||||
|
||||
return createStackedBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DStackedBarChart.equals(type))
|
||||
{
|
||||
return create3DStackedBarChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DPieChart.equals(type))
|
||||
{
|
||||
return create3DPieChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_PieChart.equals(type))
|
||||
{
|
||||
return createPieChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_3DLineChart.equals(type))
|
||||
{
|
||||
return create3DLineChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_AreaChart.equals(type))
|
||||
{
|
||||
return createAreaChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_StackedAreaChart.equals(type))
|
||||
{
|
||||
return createStackedAreaChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_LineChart.equals(type))
|
||||
{
|
||||
if ( isTimeSeries() )
|
||||
return createTimeSeriesChart();
|
||||
return createLineChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_RingChart.equals(type))
|
||||
{
|
||||
return createRingChart();
|
||||
}
|
||||
else if (MChart.CHARTTYPE_WaterfallChart.equals(type))
|
||||
{
|
||||
return createWaterfallChart();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("unknown chart type=" + type);
|
||||
}
|
||||
}
|
||||
|
||||
private JFreeChart createXYBarChart() {
|
||||
JFreeChart chart = ChartFactory.createXYBarChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
true,
|
||||
getRangeLabel(), // range axis label
|
||||
getXYDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createTimeSeriesChart() {
|
||||
JFreeChart chart = ChartFactory.createTimeSeriesChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getXYDataset(), // data
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createWaterfallChart() {
|
||||
JFreeChart chart = ChartFactory.createWaterfallChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createRingChart() {
|
||||
final JFreeChart chart = ChartFactory.createRingChart(getName(),
|
||||
getPieDataset(), isDisplayLegend(), true, true);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createPieChart() {
|
||||
final JFreeChart chart = ChartFactory.createPieChart(getName(),
|
||||
getPieDataset(), false, true, true);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DPieChart() {
|
||||
final JFreeChart chart = ChartFactory.createPieChart3D(getName(),
|
||||
getPieDataset(), false, true, true);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createBarChart() {
|
||||
JFreeChart chart = ChartFactory.createBarChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
BarRenderer renderer = new BarRenderer();
|
||||
renderer.setBarPainter(new StandardBarPainter());
|
||||
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
plot.setRenderer(renderer);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DBarChart() {
|
||||
JFreeChart chart = ChartFactory.createBarChart3D(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createStackedBarChart() {
|
||||
JFreeChart chart = ChartFactory.createStackedBarChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
BarRenderer renderer = new BarRenderer();
|
||||
renderer.setBarPainter(new StandardBarPainter());
|
||||
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
plot.setRenderer(renderer);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DStackedBarChart() {
|
||||
JFreeChart chart = ChartFactory.createStackedBarChart3D(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createAreaChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createAreaChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createStackedAreaChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createStackedAreaChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart createLineChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createLineChart(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private JFreeChart create3DLineChart() {
|
||||
// create the chart...
|
||||
JFreeChart chart = ChartFactory.createLineChart3D(
|
||||
getName(), // chart title
|
||||
getDomainLabel(), // domain axis label
|
||||
getRangeLabel(), // range axis label
|
||||
getCategoryDataset(), // data
|
||||
X_AD_Chart.CHARTORIENTATION_Horizontal.equals(getChartOrientation())
|
||||
? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, // orientation
|
||||
isDisplayLegend(), // include legend
|
||||
true, // tooltips?
|
||||
true // URLs?
|
||||
);
|
||||
|
||||
|
||||
setupCategoryChart(chart);
|
||||
return chart;
|
||||
}
|
||||
|
||||
private void setupCategoryChart(JFreeChart chart) {
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
CategoryAxis xAxis = (CategoryAxis)plot.getDomainAxis();
|
||||
xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
|
||||
|
||||
CategoryItemRenderer renderer = plot.getRenderer();
|
||||
renderer.setSeriesPaint(0, Color.RED);
|
||||
renderer.setSeriesPaint(1, Color.BLUE);
|
||||
renderer.setSeriesPaint(2, Color.YELLOW);
|
||||
renderer.setSeriesPaint(3, Color.GREEN);
|
||||
renderer.setSeriesPaint(4, Color.ORANGE);
|
||||
renderer.setSeriesPaint(5, Color.CYAN);
|
||||
renderer.setSeriesPaint(6, Color.MAGENTA);
|
||||
renderer.setSeriesPaint(7, Color.GRAY);
|
||||
renderer.setSeriesPaint(8, Color.PINK);
|
||||
|
||||
plot.setRenderer(renderer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,29 +3,14 @@ package org.compiere.model;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.DBException;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
import org.jfree.data.category.DefaultCategoryDataset;
|
||||
import org.jfree.data.general.Dataset;
|
||||
import org.jfree.data.general.DefaultPieDataset;
|
||||
import org.jfree.data.time.Day;
|
||||
import org.jfree.data.time.Month;
|
||||
import org.jfree.data.time.Quarter;
|
||||
import org.jfree.data.time.RegularTimePeriod;
|
||||
import org.jfree.data.time.TimeSeries;
|
||||
import org.jfree.data.time.TimeSeriesCollection;
|
||||
import org.jfree.data.time.Week;
|
||||
import org.jfree.data.time.Year;
|
||||
|
||||
public class MChartDatasource extends X_AD_ChartDatasource {
|
||||
|
||||
|
@ -43,209 +28,6 @@ public class MChartDatasource extends X_AD_ChartDatasource {
|
|||
super(ctx, rs, trxName);
|
||||
}
|
||||
|
||||
public void addData(MChart parent) {
|
||||
|
||||
String value = getValueColumn();
|
||||
String category;
|
||||
String unit = "D";
|
||||
|
||||
if ( !parent.isTimeSeries() )
|
||||
category = getCategoryColumn();
|
||||
else
|
||||
{
|
||||
if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Week))
|
||||
{
|
||||
unit = "W";
|
||||
}
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Month))
|
||||
{
|
||||
unit = "MM";
|
||||
}
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Quarter))
|
||||
{
|
||||
unit = "Q";
|
||||
}
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Year))
|
||||
{
|
||||
unit = "Y";
|
||||
}
|
||||
|
||||
category = " TRUNC(" + getDateColumn() + ", '" + unit + "') ";
|
||||
}
|
||||
|
||||
String series = DB.TO_STRING(getName());
|
||||
boolean hasSeries = false;
|
||||
if (getSeriesColumn() != null)
|
||||
{
|
||||
series = getSeriesColumn();
|
||||
hasSeries = true;
|
||||
}
|
||||
|
||||
String where = getWhereClause();
|
||||
if ( !Util.isEmpty(where))
|
||||
{
|
||||
where = Env.parseContext(getCtx(), parent.getWindowNo(), where, true);
|
||||
}
|
||||
|
||||
boolean hasWhere = false;
|
||||
|
||||
String sql = "SELECT " + value + ", " + category + ", " + series
|
||||
+ " FROM " + getFromClause();
|
||||
if ( !Util.isEmpty(where))
|
||||
{
|
||||
sql += " WHERE " + where;
|
||||
hasWhere = true;
|
||||
}
|
||||
|
||||
Date currentDate = Env.getContextAsDate(getCtx(), "#Date");
|
||||
Date startDate = null;
|
||||
Date endDate = null;
|
||||
|
||||
int scope = parent.getTimeScope();
|
||||
int offset = getTimeOffset();
|
||||
|
||||
if ( parent.isTimeSeries() && scope != 0 )
|
||||
{
|
||||
offset += -scope;
|
||||
startDate = increment(currentDate, parent.getTimeUnit(), offset);
|
||||
endDate = increment(startDate, parent.getTimeUnit(), scope);
|
||||
}
|
||||
|
||||
if ( startDate != null && endDate != null )
|
||||
{
|
||||
sql += hasWhere ? " AND " : " WHERE ";
|
||||
sql += category + ">=TRUNC(" + DB.TO_DATE(new Timestamp(startDate.getTime())) + ", '" + unit + "') AND ";
|
||||
sql += category + "<=TRUNC(" + DB.TO_DATE(new Timestamp(endDate.getTime())) + ", '" + unit + "') ";
|
||||
}
|
||||
|
||||
if (sql.indexOf('@') >= 0) {
|
||||
sql = Env.parseContext(getCtx(), 0, sql, false, true);
|
||||
}
|
||||
|
||||
MRole role = MRole.getDefault(getCtx(), false);
|
||||
sql = role.addAccessSQL(sql, null, true, false);
|
||||
|
||||
if (hasSeries)
|
||||
sql += " GROUP BY " + series + ", " + category + " ORDER BY " + series + ", " + category;
|
||||
else
|
||||
sql += " GROUP BY " + category + " ORDER BY " + category;
|
||||
|
||||
log.log(Level.FINE, sql);
|
||||
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
TimeSeries tseries = null;
|
||||
Dataset dataset = parent.getDataset();
|
||||
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
rs = pstmt.executeQuery();
|
||||
while(rs.next())
|
||||
{
|
||||
|
||||
String key = rs.getString(2);
|
||||
String seriesName = rs.getString(3);
|
||||
if (seriesName == null)
|
||||
seriesName = getName();
|
||||
String queryWhere = "";
|
||||
if ( hasWhere )
|
||||
queryWhere += where + " AND ";
|
||||
|
||||
queryWhere += series + " = " + DB.TO_STRING(seriesName) + " AND " + category + " = " ;
|
||||
|
||||
if ( parent.isTimeSeries() && dataset instanceof TimeSeriesCollection )
|
||||
{
|
||||
|
||||
if ( tseries == null || !tseries.getKey().equals(seriesName))
|
||||
{
|
||||
if (tseries != null)
|
||||
((TimeSeriesCollection) dataset).addSeries(tseries);
|
||||
|
||||
tseries = new TimeSeries(seriesName);
|
||||
}
|
||||
|
||||
Date date = rs.getDate(2);
|
||||
RegularTimePeriod period = null;
|
||||
|
||||
if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Day))
|
||||
period = new Day(date);
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Week))
|
||||
period = new Week(date);
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Month))
|
||||
period = new Month(date);
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Quarter))
|
||||
period = new Quarter(date);
|
||||
else if ( parent.getTimeUnit().equals(MChart.TIMEUNIT_Year))
|
||||
period = new Year(date);
|
||||
|
||||
tseries.add(period, rs.getBigDecimal(1));
|
||||
key = period.toString();
|
||||
queryWhere += DB.TO_DATE(new Timestamp(date.getTime()));
|
||||
}
|
||||
else {
|
||||
queryWhere += DB.TO_STRING(key);
|
||||
}
|
||||
|
||||
MQuery query = new MQuery(getAD_Table_ID());
|
||||
String keyCol = MTable.get(getCtx(), getAD_Table_ID()).getKeyColumns()[0];
|
||||
String whereClause = keyCol + " IN (SELECT " + getKeyColumn() + " FROM "
|
||||
+ getFromClause() + " WHERE " + queryWhere + " )";
|
||||
query.addRestriction(whereClause.toString());
|
||||
query.setRecordCount(1);
|
||||
|
||||
HashMap<String, MQuery> map = parent.getQueries();
|
||||
|
||||
if ( dataset instanceof DefaultPieDataset) {
|
||||
((DefaultPieDataset) dataset).setValue(key, rs.getBigDecimal(1));
|
||||
map.put(key, query);
|
||||
}
|
||||
else if ( dataset instanceof DefaultCategoryDataset ) {
|
||||
((DefaultCategoryDataset) dataset).addValue(rs.getBigDecimal(1), seriesName, key);
|
||||
map.put(seriesName + "__" + key, query);
|
||||
}
|
||||
else if (dataset instanceof TimeSeriesCollection )
|
||||
{
|
||||
map.put(seriesName + "__" + key, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new DBException(e, sql);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
|
||||
if (tseries != null)
|
||||
((TimeSeriesCollection) dataset).addSeries(tseries);
|
||||
|
||||
}
|
||||
|
||||
private Date increment(Date lastDate, String timeUnit, int qty) {
|
||||
|
||||
if ( lastDate == null )
|
||||
return null;
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(lastDate);
|
||||
|
||||
if ( timeUnit.equals(MChart.TIMEUNIT_Day))
|
||||
cal.add(Calendar.DAY_OF_YEAR, qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Week))
|
||||
cal.add(Calendar.WEEK_OF_YEAR, qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Month))
|
||||
cal.add(Calendar.MONTH, qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Quarter))
|
||||
cal.add(Calendar.MONTH, 3*qty);
|
||||
else if ( timeUnit.equals(MChart.TIMEUNIT_Year))
|
||||
cal.add(Calendar.YEAR, qty);
|
||||
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert date formatted as yyyy-MM to yyyy-QQ
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.awt.event.ActionListener;
|
|||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.VetoableChangeListener;
|
||||
|
||||
import org.adempiere.apps.graph.ChartBuilder;
|
||||
import org.compiere.apps.AEnv;
|
||||
import org.compiere.model.GridField;
|
||||
import org.compiere.model.MChart;
|
||||
|
@ -34,6 +35,7 @@ public class VChart extends CPanel implements ChartMouseListener, VEditor {
|
|||
private static final long serialVersionUID = 1L;
|
||||
ChartPanel chartPanel;
|
||||
MChart chartModel;
|
||||
private ChartBuilder chartBuilder;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -52,7 +54,8 @@ public class VChart extends CPanel implements ChartMouseListener, VEditor {
|
|||
|
||||
public void createChart()
|
||||
{
|
||||
JFreeChart chart = chartModel.createChart();
|
||||
chartBuilder = new ChartBuilder(chartModel);
|
||||
JFreeChart chart = chartBuilder.createChart();
|
||||
if (chartPanel != null)
|
||||
remove(chartPanel);
|
||||
|
||||
|
@ -131,7 +134,7 @@ public class VChart extends CPanel implements ChartMouseListener, VEditor {
|
|||
if ( key == null )
|
||||
return;
|
||||
|
||||
MQuery query = chartModel.getQuery(seriesName == null ? key : seriesName+"__"+key);
|
||||
MQuery query = chartBuilder.getQuery(seriesName == null ? key : seriesName+"__"+key);
|
||||
|
||||
if (query != null)
|
||||
AEnv.zoom(query);
|
||||
|
|
|
@ -34,6 +34,7 @@ Export-Package: fi.jawsy.jawwa.zk.atmosphere,
|
|||
org.adempiere.webui.apps,
|
||||
org.adempiere.webui.apps.form,
|
||||
org.adempiere.webui.apps.graph,
|
||||
org.adempiere.webui.apps.graph.model,
|
||||
org.adempiere.webui.apps.wf,
|
||||
org.adempiere.webui.component,
|
||||
org.adempiere.webui.component.test,
|
||||
|
@ -85,4 +86,4 @@ Bundle-Activator: org.adempiere.webui.WebUIActivator
|
|||
Eclipse-ExtensibleAPI: true
|
||||
Eclipse-RegisterBuddy: org.zkoss.zk.library
|
||||
Web-ContextPath: webui
|
||||
Service-Component: OSGI-INF/reportviewerprovider.xml, OSGI-INF/defaultinfofactory.xml, OSGI-INF/defaulteditorfactory.xml, OSGI-INF/jrviewerprovider.xml, OSGI-INF/resourcefinder.xml, OSGI-INF/defaultpaymentformfactory.xml, OSGI-INF/processfactory.xml, OSGI-INF/defaultprintshippinglabel.xml, OSGI-INF/defaultcreatefromfactory.xml, OSGI-INF/defaultformfactory.xml, OSGI-INF/feedbackservice.xml, OSGI-INF/zulgadgetfactory.xml
|
||||
Service-Component: OSGI-INF/reportviewerprovider.xml, OSGI-INF/defaultinfofactory.xml, OSGI-INF/defaulteditorfactory.xml, OSGI-INF/jrviewerprovider.xml, OSGI-INF/resourcefinder.xml, OSGI-INF/defaultpaymentformfactory.xml, OSGI-INF/processfactory.xml, OSGI-INF/defaultprintshippinglabel.xml, OSGI-INF/defaultcreatefromfactory.xml, OSGI-INF/defaultformfactory.xml, OSGI-INF/feedbackservice.xml, OSGI-INF/zulgadgetfactory.xml, OSGI-INF/jfgchartrenderer.xml
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.webui.apps.graph.jfreegraph.ChartRendererServiceImpl">
|
||||
<implementation class="org.adempiere.webui.apps.graph.jfreegraph.ChartRendererServiceImpl"/>
|
||||
<property name="service.ranking" type="Integer" value="0"/>
|
||||
<service>
|
||||
<provide interface="org.adempiere.webui.apps.graph.IChartRendererService"/>
|
||||
</service>
|
||||
</scr:component>
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph;
|
||||
|
||||
import org.adempiere.webui.apps.graph.model.ChartModel;
|
||||
import org.adempiere.webui.apps.graph.model.GoalModel;
|
||||
import org.adempiere.webui.apps.graph.model.IndicatorModel;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
|
||||
/**
|
||||
* Chart renderer service. Note that implementation must be thread safe.
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public interface IChartRendererService {
|
||||
|
||||
/**
|
||||
* render indicator chart for PA_Goal
|
||||
* @param parent
|
||||
* @param chartWidth
|
||||
* @param chartHeight
|
||||
* @param model
|
||||
*/
|
||||
public void renderPerformanceIndicator(Component parent, int chartWidth, int chartHeight, IndicatorModel model);
|
||||
|
||||
/**
|
||||
* render chart for PA_Goal
|
||||
* @param parent
|
||||
* @param chartWidth
|
||||
* @param chartHeight
|
||||
* @param goalModel
|
||||
*/
|
||||
public void renderPerformanceGraph(Component parent, int chartWidth, int chartHeight, GoalModel goalModel);
|
||||
|
||||
/**
|
||||
* render chart for AD_Chart
|
||||
* @param parent
|
||||
* @param width
|
||||
* @param height
|
||||
* @param chartModel
|
||||
*/
|
||||
public void renderChart(Component parent, int width, int height, ChartModel chartModel);
|
||||
}
|
|
@ -14,15 +14,14 @@
|
|||
package org.adempiere.webui.apps.graph;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.adempiere.apps.graph.GraphBuilder;
|
||||
import org.adempiere.apps.graph.GraphColumn;
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.apps.graph.model.GoalModel;
|
||||
import org.adempiere.webui.editor.WTableDirEditor;
|
||||
import org.adempiere.webui.event.ValueChangeEvent;
|
||||
import org.adempiere.webui.event.ValueChangeListener;
|
||||
|
@ -30,19 +29,10 @@ import org.compiere.model.MGoal;
|
|||
import org.compiere.model.MLookup;
|
||||
import org.compiere.model.MLookupFactory;
|
||||
import org.compiere.model.MLookupInfo;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.model.MMeasure;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.jfree.chart.ChartMouseEvent;
|
||||
import org.jfree.chart.ChartRenderingInfo;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.encoders.EncoderUtil;
|
||||
import org.jfree.chart.encoders.ImageFormat;
|
||||
import org.jfree.chart.entity.CategoryItemEntity;
|
||||
import org.jfree.chart.entity.ChartEntity;
|
||||
import org.jfree.chart.entity.PieSectionEntity;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.zhtml.A;
|
||||
import org.zkoss.zhtml.Br;
|
||||
import org.zkoss.zhtml.Table;
|
||||
|
@ -54,13 +44,10 @@ import org.zkoss.zk.ui.IdSpace;
|
|||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.event.MouseEvent;
|
||||
import org.zkoss.zul.Borderlayout;
|
||||
import org.zkoss.zul.Center;
|
||||
import org.zkoss.zul.East;
|
||||
import org.zkoss.zul.Area;
|
||||
import org.zkoss.zul.Div;
|
||||
import org.zkoss.zul.Imagemap;
|
||||
import org.zkoss.zul.Panel;
|
||||
import org.zkoss.zul.Panelchildren;
|
||||
import org.zkoss.zul.Toolbar;
|
||||
|
@ -100,18 +87,21 @@ public class WGraph extends Div implements IdSpace {
|
|||
*/
|
||||
ArrayList<GraphColumn> list = new ArrayList<GraphColumn>();
|
||||
|
||||
private GraphBuilder builder;
|
||||
|
||||
private boolean m_chartSelection;
|
||||
|
||||
private int zoomFactor = 0;
|
||||
|
||||
private MGoal m_goal;
|
||||
|
||||
private String m_xAxisLabel;
|
||||
|
||||
private String m_yAxisLabel;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public WGraph() {
|
||||
super();
|
||||
builder = new GraphBuilder();
|
||||
panel = new Panel();
|
||||
} // BarGraph
|
||||
|
||||
|
@ -154,9 +144,9 @@ public class WGraph extends Div implements IdSpace {
|
|||
*/
|
||||
public void setGoal(MGoal goal)
|
||||
{
|
||||
builder.setMGoal(goal);
|
||||
builder.setYAxisLabel(goal.getName());
|
||||
builder.setXAxisLabel(goal.getXAxisText());
|
||||
m_goal = goal;
|
||||
m_yAxisLabel = goal.getName();
|
||||
m_xAxisLabel = goal.getXAxisText();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,10 +184,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
}
|
||||
|
||||
if (m_renderChart) {
|
||||
JFreeChart chart = builder.createChart(builder.getMGoal()
|
||||
.getChartType());
|
||||
|
||||
render(chart);
|
||||
renderChart((String)null);
|
||||
}
|
||||
if (m_renderTable) {
|
||||
if (m_renderChart) {
|
||||
|
@ -218,8 +205,16 @@ public class WGraph extends Div implements IdSpace {
|
|||
}
|
||||
|
||||
private void loadData() {
|
||||
list = builder.loadData();
|
||||
// Calculated
|
||||
MMeasure measure = m_goal.getMeasure();
|
||||
if (measure == null)
|
||||
{
|
||||
log.warning("No Measure for " + m_goal);
|
||||
return;
|
||||
}
|
||||
|
||||
list = measure.getGraphColumnList(m_goal);
|
||||
|
||||
if (m_renderChart && m_chartSelection) {
|
||||
Toolbar toolbar = new Toolbar();
|
||||
panel.appendChild(toolbar);
|
||||
|
@ -239,95 +234,32 @@ public class WGraph extends Div implements IdSpace {
|
|||
Object value = evt.getNewValue();
|
||||
if (value == null || value.toString().trim().length() == 0)
|
||||
return;
|
||||
JFreeChart chart = null;
|
||||
chart = builder.createChart(value.toString());
|
||||
if (chart != null)
|
||||
render(chart);
|
||||
renderChart(value.toString());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
} // loadData
|
||||
|
||||
private void render(JFreeChart chart) {
|
||||
ChartRenderingInfo info = new ChartRenderingInfo();
|
||||
private void renderChart(String type) {
|
||||
int width = 560;
|
||||
int height = 400;
|
||||
if (zoomFactor > 0) {
|
||||
width = width * zoomFactor / 100;
|
||||
height = height * zoomFactor / 100;
|
||||
}
|
||||
if (m_hideTitle) {
|
||||
chart.setTitle("");
|
||||
}
|
||||
BufferedImage bi = chart.createBufferedImage(width, height,
|
||||
BufferedImage.TRANSLUCENT, info);
|
||||
try {
|
||||
byte[] bytes = EncoderUtil.encode(bi, ImageFormat.PNG, true);
|
||||
|
||||
AImage image = new AImage("", bytes);
|
||||
Imagemap myImage = new Imagemap();
|
||||
|
||||
myImage.setContent(image);
|
||||
if (panel.getPanelchildren() != null) {
|
||||
panel.getPanelchildren().getChildren().clear();
|
||||
panel.getPanelchildren().appendChild(myImage);
|
||||
} else {
|
||||
Panelchildren pc = new Panelchildren();
|
||||
panel.appendChild(pc);
|
||||
pc.appendChild(myImage);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Iterator<?> it = info.getEntityCollection().getEntities()
|
||||
.iterator(); it.hasNext();) {
|
||||
ChartEntity entity = (ChartEntity) it.next();
|
||||
|
||||
String key = null;
|
||||
if (entity instanceof CategoryItemEntity) {
|
||||
Comparable<?> colKey = ((CategoryItemEntity) entity)
|
||||
.getColumnKey();
|
||||
if (colKey != null) {
|
||||
key = colKey.toString();
|
||||
}
|
||||
} else if (entity instanceof PieSectionEntity) {
|
||||
Comparable<?> sectionKey = ((PieSectionEntity) entity)
|
||||
.getSectionKey();
|
||||
if (sectionKey != null) {
|
||||
key = sectionKey.toString();
|
||||
}
|
||||
}
|
||||
if (key == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Area area = new Area();
|
||||
myImage.appendChild(area);
|
||||
area.setCoords(entity.getShapeCoords());
|
||||
area.setShape(entity.getShapeType());
|
||||
area.setTooltiptext(entity.getToolTipText());
|
||||
area.setId(count+"_WG_" + key);
|
||||
count++;
|
||||
}
|
||||
|
||||
myImage.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
||||
public void onEvent(Event event) throws Exception {
|
||||
MouseEvent me = (MouseEvent) event;
|
||||
String areaId = me.getArea();
|
||||
if (areaId != null) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String s = "_WG_" + list.get(i).getLabel();
|
||||
if (areaId.endsWith(s)) {
|
||||
chartMouseClicked(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "", e);
|
||||
if (panel.getPanelchildren() != null) {
|
||||
panel.getPanelchildren().getChildren().clear();
|
||||
} else {
|
||||
Panelchildren pc = new Panelchildren();
|
||||
panel.appendChild(pc);
|
||||
}
|
||||
IChartRendererService renderer = Service.locator().locate(IChartRendererService.class).getService();
|
||||
GoalModel goalModel = new GoalModel();
|
||||
goalModel.goal = m_goal;
|
||||
goalModel.chartType = type != null ? type : m_goal.getChartType();
|
||||
goalModel.columnList = Collections.unmodifiableList(list);
|
||||
goalModel.showTitle = !m_hideTitle;
|
||||
goalModel.xAxisLabel = m_xAxisLabel;
|
||||
goalModel.yAxisLabel = m_yAxisLabel;
|
||||
goalModel.zoomFactor = zoomFactor;
|
||||
renderer.renderPerformanceGraph(panel.getPanelchildren(), width, height, goalModel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,7 +275,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
* @return Returns the x_AxisLabel.
|
||||
*/
|
||||
public String getX_AxisLabel() {
|
||||
return builder.getXAxisLabel();
|
||||
return m_xAxisLabel;
|
||||
} // getX_AxisLabel
|
||||
|
||||
/**
|
||||
|
@ -351,14 +283,14 @@ public class WGraph extends Div implements IdSpace {
|
|||
* The x_AxisLabel to set.
|
||||
*/
|
||||
public void setX_AxisLabel(String axisLabel) {
|
||||
builder.setXAxisLabel(axisLabel);
|
||||
m_xAxisLabel = axisLabel;
|
||||
} // setX_AxisLabel
|
||||
|
||||
/**
|
||||
* @return Returns the y_AxisLabel.
|
||||
*/
|
||||
public String getY_AxisLabel() {
|
||||
return builder.getYAxisLabel();
|
||||
return m_yAxisLabel;
|
||||
} // getY_AxisLabel
|
||||
|
||||
/**
|
||||
|
@ -366,7 +298,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
* The y_AxisLabel to set.
|
||||
*/
|
||||
public void setY_AxisLabel(String axisLabel) {
|
||||
builder.setYAxisLabel(axisLabel);
|
||||
m_yAxisLabel = axisLabel;
|
||||
} // setY_AxisLabel
|
||||
|
||||
/**
|
||||
|
@ -431,27 +363,6 @@ public class WGraph extends Div implements IdSpace {
|
|||
m_renderChart = mRenderChart;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Paint Component
|
||||
*
|
||||
* @param g
|
||||
* graphics
|
||||
*/
|
||||
|
||||
public void chartMouseClicked(int index) {
|
||||
GraphColumn bgc = list.get(index);
|
||||
if (null == bgc)
|
||||
return;
|
||||
MQuery query = bgc.getMQuery(builder.getMGoal());
|
||||
if (query != null)
|
||||
AEnv.zoom(query);
|
||||
else
|
||||
log.warning("Nothing to zoom to - " + bgc);
|
||||
}
|
||||
|
||||
public void chartMouseMoved(ChartMouseEvent event) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return GraphColumn[]
|
||||
|
@ -484,7 +395,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
td.setDynamicProperty("colspan", "2");
|
||||
td.setSclass("pa-tdcontent");
|
||||
tr.appendChild(td);
|
||||
text = new Text(builder.getMGoal().getMeasureTarget().setScale(2,
|
||||
text = new Text(m_goal.getMeasureTarget().setScale(2,
|
||||
BigDecimal.ROUND_HALF_UP).toPlainString());
|
||||
td.appendChild(text);
|
||||
|
||||
|
@ -499,7 +410,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
td.setDynamicProperty("colspan", "2");
|
||||
td.setSclass("pa-tdcontent");
|
||||
tr.appendChild(td);
|
||||
text = new Text(builder.getMGoal().getMeasureActual().setScale(2,
|
||||
text = new Text(m_goal.getMeasureActual().setScale(2,
|
||||
BigDecimal.ROUND_HALF_UP).toPlainString());
|
||||
td.appendChild(text);
|
||||
|
||||
|
@ -512,7 +423,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
td.setDynamicProperty("rowspan", bList.length);
|
||||
td.setSclass("pa-label");
|
||||
td.setDynamicProperty("valign", "top");
|
||||
text = new Text(builder.getMGoal().getXAxisText());
|
||||
text = new Text(m_goal.getXAxisText());
|
||||
td.appendChild(text);
|
||||
|
||||
for (int k = 0; k < bList.length; k++) {
|
||||
|
@ -531,7 +442,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
td.setSclass("pa-tdvalue");
|
||||
tr.appendChild(td);
|
||||
BigDecimal value = BigDecimal.valueOf(bgc.getValue());
|
||||
if (bgc.getMQuery(builder.getMGoal()) != null) {
|
||||
if (bgc.getMQuery(m_goal) != null) {
|
||||
A a = new A();
|
||||
a.setSclass("pa-hrefNode");
|
||||
td.appendChild(a);
|
||||
|
@ -545,8 +456,7 @@ public class WGraph extends Div implements IdSpace {
|
|||
int index = Integer.parseInt(String.valueOf(ss));
|
||||
GraphColumn[] colList = getGraphColumnList();
|
||||
if ((index >= 0) && (index < colList.length))
|
||||
AEnv.zoom(colList[index].getMQuery(builder
|
||||
.getMGoal()));
|
||||
AEnv.zoom(colList[index].getMQuery(m_goal));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,11 +474,11 @@ public class WGraph extends Div implements IdSpace {
|
|||
td = new Td();
|
||||
td.setDynamicProperty("colspan", "3");
|
||||
tr.appendChild(td);
|
||||
text = new Text(builder.getMGoal().getDescription());
|
||||
text = new Text(m_goal.getDescription());
|
||||
td.appendChild(text);
|
||||
Br br = new Br();
|
||||
td.appendChild(br);
|
||||
text = new Text(stripHtml(builder.getMGoal().getColorSchema()
|
||||
text = new Text(stripHtml(m_goal.getColorSchema()
|
||||
.getDescription(), true));
|
||||
td.appendChild(text);
|
||||
}
|
||||
|
|
|
@ -66,8 +66,6 @@ public class WPAPanel extends Panel implements EventListener<Event>
|
|||
setSclass("performance-panel");
|
||||
Grid grid = new Grid();
|
||||
appendChild(grid);
|
||||
int gh = options != null && options.chartHeight > 0 ? options.chartHeight+60 : 180;
|
||||
grid.setHeight((m_goals.length + (m_goals.length % 2)) * gh / 2 + "px");
|
||||
grid.makeNoStrip();
|
||||
|
||||
Rows rows = new Rows();
|
||||
|
|
|
@ -13,36 +13,22 @@
|
|||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.webui.apps.graph.model.IndicatorModel;
|
||||
import org.adempiere.webui.component.Panel;
|
||||
import org.adempiere.webui.theme.ThemeManager;
|
||||
import org.compiere.model.MColorSchema;
|
||||
import org.compiere.model.MGoal;
|
||||
import org.compiere.util.DisplayType;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.encoders.EncoderUtil;
|
||||
import org.jfree.chart.encoders.ImageFormat;
|
||||
import org.jfree.chart.plot.DialShape;
|
||||
import org.jfree.chart.plot.MeterInterval;
|
||||
import org.jfree.chart.plot.MeterPlot;
|
||||
import org.jfree.data.Range;
|
||||
import org.jfree.data.general.DefaultValueDataset;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zul.Image;
|
||||
import org.zkoss.zul.Menuitem;
|
||||
import org.zkoss.zul.Menupopup;
|
||||
|
||||
|
@ -135,11 +121,24 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
return m_goal;
|
||||
} // getGoal
|
||||
|
||||
private JFreeChart createChart()
|
||||
/**
|
||||
* Init Graph Display
|
||||
* Kinamo (pelgrim)
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
JFreeChart chart = null;
|
||||
|
||||
// Set Text
|
||||
IChartRendererService renderer = Service.locator().locate(IChartRendererService.class).getService();
|
||||
IndicatorModel model = new IndicatorModel();
|
||||
model.goalModel = m_goal;
|
||||
model.chartBackground = chartBackground;
|
||||
model.dialBackground = dialBackground;
|
||||
model.needleColor = needleColor;
|
||||
model.tickColor = tickColor;
|
||||
renderer.renderPerformanceIndicator(this, chartWidth, chartHeight, model);
|
||||
|
||||
this.getFirstChild().addEventListener(Events.ON_CLICK, this);
|
||||
|
||||
// Set Text
|
||||
StringBuilder text = new StringBuilder(m_goal.getName());
|
||||
if (m_goal.isTarget())
|
||||
text.append(": ").append(m_goal.getPercent()).append("%");
|
||||
|
@ -157,96 +156,17 @@ public class WPerformanceIndicator extends Panel implements EventListener<Event>
|
|||
text.append(" ").append(Msg.getMsg(Env.getCtx(), "of")).append(" ")
|
||||
.append(s_format.format(m_goal.getMeasureTarget()));
|
||||
setTooltiptext(text.toString());
|
||||
//
|
||||
DefaultValueDataset data = new DefaultValueDataset((float)m_goal.getPercent());
|
||||
MeterPlot plot = new MeterPlot(data);
|
||||
|
||||
MColorSchema colorSchema = m_goal.getColorSchema();
|
||||
int rangeLo = 0; int rangeHi=0;
|
||||
Point2D start = new Point2D.Float(0, 0);
|
||||
Point2D end = new Point2D.Float(50, 50);
|
||||
float[] dist = {0.0f, 0.2f, 0.45f, 0.75f, 1.0f};
|
||||
for (int i=1; i<=4; i++){
|
||||
switch (i) {
|
||||
case 1: rangeHi = colorSchema.getMark1Percent(); break;
|
||||
case 2: rangeHi = colorSchema.getMark2Percent(); break;
|
||||
case 3: rangeHi = colorSchema.getMark3Percent(); break;
|
||||
case 4: rangeHi = colorSchema.getMark4Percent(); break;
|
||||
}
|
||||
if (rangeHi==9999)
|
||||
rangeHi = (int) Math.floor(rangeLo*1.5);
|
||||
if (rangeLo < rangeHi) {
|
||||
Color[] colors = {colorSchema.getColor(rangeHi).brighter().brighter(),
|
||||
colorSchema.getColor(rangeHi).brighter(), colorSchema.getColor(rangeHi),
|
||||
colorSchema.getColor(rangeHi).darker(), colorSchema.getColor(rangeHi).darker().darker()};
|
||||
LinearGradientPaint p =
|
||||
new LinearGradientPaint(start, end, dist, colors);
|
||||
|
||||
plot.addInterval(new MeterInterval("Normal", //label
|
||||
new Range(rangeLo, rangeHi), //range
|
||||
p,
|
||||
new BasicStroke(7.0f),
|
||||
dialBackground
|
||||
));
|
||||
rangeLo = rangeHi;
|
||||
}
|
||||
}
|
||||
plot.setRange(new Range(0,rangeLo));
|
||||
plot.setDialBackgroundPaint(dialBackground);
|
||||
plot.setUnits("");
|
||||
plot.setDialShape(DialShape.CHORD);
|
||||
plot.setNeedlePaint(needleColor);
|
||||
plot.setTickSize(2000);
|
||||
plot.setTickLabelFont(new Font("SansSerif", Font.BOLD, 8));
|
||||
plot.setValueFont(new Font("SansSerif", Font.BOLD, 8));
|
||||
plot.setNoDataMessageFont(new Font("SansSerif", Font.BOLD, 8));
|
||||
plot.setTickLabelPaint(tickColor);
|
||||
plot.setValuePaint(new Color(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
plot.setTickPaint(tickColor);
|
||||
//
|
||||
chart = new JFreeChart( "", new Font("SansSerif", Font.BOLD, 9), plot,false);
|
||||
|
||||
return chart;
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Graph Display
|
||||
* Kinamo (pelgrim)
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
JFreeChart chart = createChart();
|
||||
chart.setBackgroundPaint(chartBackground);
|
||||
chart.setAntiAlias(true);
|
||||
BufferedImage bi = chart.createBufferedImage(chartWidth, chartHeight, BufferedImage.TRANSLUCENT , null);
|
||||
try {
|
||||
byte[] bytes = EncoderUtil.encode(bi, ImageFormat.PNG, true);
|
||||
|
||||
AImage image = new AImage("", bytes);
|
||||
Image myImage = new Image();
|
||||
myImage.setContent(image);
|
||||
appendChild(myImage);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update Display Data
|
||||
*/
|
||||
protected void updateDisplay()
|
||||
{
|
||||
chartPanel.setChart(createChart());
|
||||
invalidate();
|
||||
} // updateData
|
||||
|
||||
public void onEvent(Event event) throws Exception
|
||||
{
|
||||
if (event.getTarget() == this.getFirstChild())
|
||||
{
|
||||
event.stopPropagation();
|
||||
Events.sendEvent(Events.ON_CLICK, this, event.getData());
|
||||
}
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package org.adempiere.webui.util;
|
||||
package org.adempiere.webui.apps.graph.jfreegraph;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.apps.graph.ChartBuilder;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.compiere.model.MChart;
|
||||
import org.compiere.model.MQuery;
|
||||
|
@ -33,12 +34,14 @@ import org.zkoss.zul.Imagemap;
|
|||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class ChartRenderer {
|
||||
/* package */ class ChartRenderer {
|
||||
|
||||
private static final CLogger log = CLogger.getCLogger(ChartRenderer.class);
|
||||
|
||||
private MChart chartModel;
|
||||
|
||||
private ChartBuilder chartBuilder;
|
||||
|
||||
/**
|
||||
* @param chartModel
|
||||
*/
|
||||
|
@ -52,7 +55,9 @@ public class ChartRenderer {
|
|||
* @param width
|
||||
*/
|
||||
public void render(Component parent, int width, int height) {
|
||||
JFreeChart chart = chartModel.createChart();
|
||||
chartBuilder = new ChartBuilder(chartModel);
|
||||
JFreeChart chart = chartBuilder.createChart();
|
||||
chart.getPlot().setForegroundAlpha(0.6f);
|
||||
|
||||
ChartRenderingInfo info = new ChartRenderingInfo();
|
||||
BufferedImage bi = chart.createBufferedImage(width, height,
|
||||
|
@ -136,7 +141,7 @@ public class ChartRenderer {
|
|||
}
|
||||
|
||||
public void chartMouseClicked(String key, String category) {
|
||||
MQuery query = chartModel.getQuery("null".equals(category) ? key : category + "__" + key);
|
||||
MQuery query = chartBuilder.getQuery("null".equals(category) ? key : category + "__" + key);
|
||||
if (query != null)
|
||||
AEnv.zoom(query);
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
/******************************************************************************
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph.jfreegraph;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.apps.graph.GraphBuilder;
|
||||
import org.adempiere.apps.graph.GraphColumn;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.apps.graph.IChartRendererService;
|
||||
import org.adempiere.webui.apps.graph.model.ChartModel;
|
||||
import org.adempiere.webui.apps.graph.model.GoalModel;
|
||||
import org.adempiere.webui.apps.graph.model.IndicatorModel;
|
||||
import org.compiere.model.MGoal;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.jfree.chart.ChartRenderingInfo;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.encoders.EncoderUtil;
|
||||
import org.jfree.chart.encoders.ImageFormat;
|
||||
import org.jfree.chart.entity.CategoryItemEntity;
|
||||
import org.jfree.chart.entity.ChartEntity;
|
||||
import org.jfree.chart.entity.PieSectionEntity;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.event.MouseEvent;
|
||||
import org.zkoss.zul.Area;
|
||||
import org.zkoss.zul.Image;
|
||||
import org.zkoss.zul.Imagemap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class ChartRendererServiceImpl implements IChartRendererService {
|
||||
|
||||
private final static CLogger log = CLogger.getCLogger(ChartRendererServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public void renderPerformanceIndicator(Component parent, int chartWidth, int chartHeight, IndicatorModel model) {
|
||||
PerformanceGraphBuilder builder = new PerformanceGraphBuilder();
|
||||
JFreeChart chart = builder.createIndicatorChart(model);
|
||||
chart.setBackgroundPaint(model.chartBackground);
|
||||
chart.setAntiAlias(true);
|
||||
BufferedImage bi = chart.createBufferedImage(chartWidth, chartHeight, BufferedImage.TRANSLUCENT , null);
|
||||
try {
|
||||
byte[] bytes = EncoderUtil.encode(bi, ImageFormat.PNG, true);
|
||||
|
||||
AImage image = new AImage("", bytes);
|
||||
Image myImage = new Image();
|
||||
myImage.setContent(image);
|
||||
parent.appendChild(myImage);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPerformanceGraph(Component parent, int chartWidth, int chartHeight, final GoalModel goalModel) {
|
||||
GraphBuilder builder = new GraphBuilder();
|
||||
builder.setMGoal(goalModel.goal);
|
||||
builder.setXAxisLabel(goalModel.xAxisLabel);
|
||||
builder.setYAxisLabel(goalModel.yAxisLabel);
|
||||
builder.loadDataSet(goalModel.columnList);
|
||||
JFreeChart chart = builder.createChart(goalModel.chartType);
|
||||
ChartRenderingInfo info = new ChartRenderingInfo();
|
||||
chart.getPlot().setForegroundAlpha(0.6f);
|
||||
if (goalModel.zoomFactor > 0) {
|
||||
chartWidth = chartWidth * goalModel.zoomFactor / 100;
|
||||
chartHeight = chartHeight * goalModel.zoomFactor / 100;
|
||||
}
|
||||
if (!goalModel.showTitle) {
|
||||
chart.setTitle("");
|
||||
}
|
||||
BufferedImage bi = chart.createBufferedImage(chartWidth, chartHeight,
|
||||
BufferedImage.TRANSLUCENT, info);
|
||||
try {
|
||||
byte[] bytes = EncoderUtil.encode(bi, ImageFormat.PNG, true);
|
||||
|
||||
AImage image = new AImage("", bytes);
|
||||
Imagemap myImage = new Imagemap();
|
||||
|
||||
myImage.setContent(image);
|
||||
parent.appendChild(myImage);
|
||||
|
||||
int count = 0;
|
||||
for (Iterator<?> it = info.getEntityCollection().getEntities()
|
||||
.iterator(); it.hasNext();) {
|
||||
ChartEntity entity = (ChartEntity) it.next();
|
||||
|
||||
String key = null;
|
||||
if (entity instanceof CategoryItemEntity) {
|
||||
Comparable<?> colKey = ((CategoryItemEntity) entity)
|
||||
.getColumnKey();
|
||||
if (colKey != null) {
|
||||
key = colKey.toString();
|
||||
}
|
||||
} else if (entity instanceof PieSectionEntity) {
|
||||
Comparable<?> sectionKey = ((PieSectionEntity) entity)
|
||||
.getSectionKey();
|
||||
if (sectionKey != null) {
|
||||
key = sectionKey.toString();
|
||||
}
|
||||
}
|
||||
if (key == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Area area = new Area();
|
||||
myImage.appendChild(area);
|
||||
area.setCoords(entity.getShapeCoords());
|
||||
area.setShape(entity.getShapeType());
|
||||
area.setTooltiptext(entity.getToolTipText());
|
||||
area.setId(count+"_WG_" + key);
|
||||
count++;
|
||||
}
|
||||
|
||||
myImage.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
|
||||
public void onEvent(Event event) throws Exception {
|
||||
MouseEvent me = (MouseEvent) event;
|
||||
String areaId = me.getArea();
|
||||
if (areaId != null) {
|
||||
List<GraphColumn> list = goalModel.columnList;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String s = "_WG_" + list.get(i).getLabel();
|
||||
if (areaId.endsWith(s)) {
|
||||
chartMouseClicked(goalModel.goal, list.get(i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void chartMouseClicked(MGoal goal, GraphColumn bgc) {
|
||||
if (null == bgc)
|
||||
return;
|
||||
MQuery query = bgc.getMQuery(goal);
|
||||
if (query != null)
|
||||
AEnv.zoom(query);
|
||||
else
|
||||
log.warning("Nothing to zoom to - " + bgc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderChart(Component parent, int width, int height,
|
||||
ChartModel chartModel) {
|
||||
ChartRenderer renderer = new ChartRenderer(chartModel.chart);
|
||||
renderer.render(parent, width, height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph.jfreegraph;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.geom.Point2D;
|
||||
|
||||
import org.adempiere.webui.apps.graph.model.IndicatorModel;
|
||||
import org.compiere.model.MColorSchema;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.plot.DialShape;
|
||||
import org.jfree.chart.plot.MeterInterval;
|
||||
import org.jfree.chart.plot.MeterPlot;
|
||||
import org.jfree.data.Range;
|
||||
import org.jfree.data.general.DefaultValueDataset;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class PerformanceGraphBuilder {
|
||||
|
||||
public JFreeChart createIndicatorChart(IndicatorModel model)
|
||||
{
|
||||
JFreeChart chart = null;
|
||||
DefaultValueDataset data = new DefaultValueDataset((float)model.goalModel.getPercent());
|
||||
MeterPlot plot = new MeterPlot(data);
|
||||
|
||||
MColorSchema colorSchema = model.goalModel.getColorSchema();
|
||||
int rangeLo = 0; int rangeHi=0;
|
||||
Point2D start = new Point2D.Float(0, 0);
|
||||
Point2D end = new Point2D.Float(50, 50);
|
||||
float[] dist = {0.0f, 0.2f, 0.45f, 0.75f, 1.0f};
|
||||
for (int i=1; i<=4; i++){
|
||||
switch (i) {
|
||||
case 1: rangeHi = colorSchema.getMark1Percent(); break;
|
||||
case 2: rangeHi = colorSchema.getMark2Percent(); break;
|
||||
case 3: rangeHi = colorSchema.getMark3Percent(); break;
|
||||
case 4: rangeHi = colorSchema.getMark4Percent(); break;
|
||||
}
|
||||
if (rangeHi==9999)
|
||||
rangeHi = (int) Math.floor(rangeLo*1.5);
|
||||
if (rangeLo < rangeHi) {
|
||||
Color[] colors = {colorSchema.getColor(rangeHi).brighter().brighter(),
|
||||
colorSchema.getColor(rangeHi).brighter(), colorSchema.getColor(rangeHi),
|
||||
colorSchema.getColor(rangeHi).darker(), colorSchema.getColor(rangeHi).darker().darker()};
|
||||
LinearGradientPaint p =
|
||||
new LinearGradientPaint(start, end, dist, colors);
|
||||
|
||||
plot.addInterval(new MeterInterval("Normal", //label
|
||||
new Range(rangeLo, rangeHi), //range
|
||||
p,
|
||||
new BasicStroke(7.0f),
|
||||
model.dialBackground
|
||||
));
|
||||
rangeLo = rangeHi;
|
||||
}
|
||||
}
|
||||
plot.setRange(new Range(0,rangeLo));
|
||||
plot.setDialBackgroundPaint(model.dialBackground);
|
||||
plot.setUnits("");
|
||||
plot.setDialShape(DialShape.CHORD);
|
||||
plot.setNeedlePaint(model.needleColor);
|
||||
plot.setTickSize(2000);
|
||||
plot.setTickLabelFont(new Font("SansSerif", Font.BOLD, 8));
|
||||
plot.setValueFont(new Font("SansSerif", Font.BOLD, 8));
|
||||
plot.setNoDataMessageFont(new Font("SansSerif", Font.BOLD, 8));
|
||||
plot.setTickLabelPaint(model.tickColor);
|
||||
plot.setValuePaint(new Color(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
plot.setTickPaint(model.tickColor);
|
||||
//
|
||||
chart = new JFreeChart( "", new Font("SansSerif", Font.BOLD, 9), plot,false);
|
||||
|
||||
return chart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph.model;
|
||||
|
||||
import org.compiere.model.MChart;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class ChartModel {
|
||||
public MChart chart;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.adempiere.apps.graph.GraphColumn;
|
||||
import org.compiere.model.MGoal;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class GoalModel {
|
||||
public MGoal goal;
|
||||
public String chartType;
|
||||
public boolean showTitle;
|
||||
public List<GraphColumn> columnList;
|
||||
public String xAxisLabel;
|
||||
public String yAxisLabel;
|
||||
public int zoomFactor;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.webui.apps.graph.model;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.compiere.model.MGoal;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class IndicatorModel {
|
||||
public MGoal goalModel;
|
||||
public Color chartBackground;
|
||||
public Color dialBackground;
|
||||
public Color needleColor;
|
||||
public Color tickColor;
|
||||
}
|
|
@ -86,6 +86,7 @@ public class DPPerformance extends DashboardPanel {
|
|||
script = script + "grid.parent().height(grid.css('height'));}, 500);";
|
||||
if (Executions.getCurrent() != null)
|
||||
Clients.response(new AuScript(script));
|
||||
this.getFirstChild().invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,10 @@ import java.util.logging.Level;
|
|||
import org.adempiere.base.Service;
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.apps.graph.IChartRendererService;
|
||||
import org.adempiere.webui.apps.graph.WGraph;
|
||||
import org.adempiere.webui.apps.graph.WPerformanceDetail;
|
||||
import org.adempiere.webui.apps.graph.model.ChartModel;
|
||||
import org.adempiere.webui.component.ToolBarButton;
|
||||
import org.adempiere.webui.dashboard.DashboardPanel;
|
||||
import org.adempiere.webui.dashboard.DashboardRunnable;
|
||||
|
@ -38,7 +40,6 @@ import org.adempiere.webui.factory.IDashboardGadgetFactory;
|
|||
import org.adempiere.webui.report.HTMLExtension;
|
||||
import org.adempiere.webui.session.SessionManager;
|
||||
import org.adempiere.webui.theme.ThemeManager;
|
||||
import org.adempiere.webui.util.ChartRenderer;
|
||||
import org.adempiere.webui.window.ZkReportViewerProvider;
|
||||
import org.compiere.model.I_AD_Menu;
|
||||
import org.compiere.model.MChart;
|
||||
|
@ -382,7 +383,6 @@ public class DashboardController implements EventListener<Event> {
|
|||
chartPanel.addEventListener(Events.ON_AFTER_SIZE, new EventListener<AfterSizeEvent>() {
|
||||
@Override
|
||||
public void onEvent(AfterSizeEvent event) throws Exception {
|
||||
ChartRenderer renderer = new ChartRenderer(chartModel);
|
||||
int width = event.getWidth()*90/100;
|
||||
int height = event.getHeight();
|
||||
//set normal height
|
||||
|
@ -391,7 +391,10 @@ public class DashboardController implements EventListener<Event> {
|
|||
chartPanel.setHeight(height+"px");
|
||||
}
|
||||
chartPanel.getChildren().clear();
|
||||
renderer.render(chartPanel, width, height);
|
||||
ChartModel model = new ChartModel();
|
||||
model.chart = chartModel;
|
||||
IChartRendererService renderer = Service.locator().locate(IChartRendererService.class).getService();
|
||||
renderer.renderChart(chartPanel, width, height, model);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
package org.adempiere.webui.editor;
|
||||
|
||||
|
||||
import org.adempiere.webui.util.ChartRenderer;
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.webui.apps.graph.IChartRendererService;
|
||||
import org.adempiere.webui.apps.graph.model.ChartModel;
|
||||
import org.compiere.model.GridField;
|
||||
import org.compiere.model.MChart;
|
||||
import org.compiere.util.CLogger;
|
||||
|
@ -50,7 +52,6 @@ public class WChartEditor extends WEditor
|
|||
}
|
||||
|
||||
private void createChart() {
|
||||
ChartRenderer renderer = new ChartRenderer(chartModel);
|
||||
Panel panel = getComponent();
|
||||
if (panel.getPanelchildren() != null) {
|
||||
panel.getPanelchildren().getChildren().clear();
|
||||
|
@ -59,7 +60,10 @@ public class WChartEditor extends WEditor
|
|||
panel.appendChild(pc);
|
||||
pc.setSclass("chart-field");
|
||||
}
|
||||
renderer.render(panel.getPanelchildren(), 400, chartModel.getWinHeight());
|
||||
ChartModel model = new ChartModel();
|
||||
model.chart = chartModel;
|
||||
IChartRendererService renderer = Service.locator().locate(IChartRendererService.class).getService();
|
||||
renderer.renderChart(panel.getPanelchildren(), 400, chartModel.getWinHeight(), model);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,8 @@ bin.includes = META-INF/,\
|
|||
OSGI-INF/feedbackservice.xml,\
|
||||
sessiontimeout.zul,\
|
||||
*.jsp,\
|
||||
labelapplet.jar
|
||||
labelapplet.jar,\
|
||||
OSGI-INF/jfgchartrenderer.xml
|
||||
src.includes = WEB-INF/classes/,\
|
||||
WEB-INF/tld/,\
|
||||
WEB-INF/web.xml,\
|
||||
|
|
|
@ -1660,15 +1660,16 @@ table.z-vbox > tbody > tr > td > table {
|
|||
.performance-indicator {
|
||||
margin: auto;
|
||||
position: relative;
|
||||
width: 120px !important;
|
||||
}
|
||||
|
||||
.performance-indicator img {
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.window-view-pi .performance-indicator {
|
||||
.window-view-pi .performance-indicator img {
|
||||
width: 180px !important;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue