introducing charts

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-analysis/EcologicalEngine@112285 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Gianpaolo Coro 2015-03-02 12:36:53 +00:00
parent 937d559ae4
commit 4b623558d4
8 changed files with 696 additions and 92 deletions

View File

@ -45,7 +45,10 @@ import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.gcube.contentmanagement.graphtools.abstracts.GenericStandaloneGraph;
@ -323,6 +326,58 @@ public class TransectLineGraph extends GenericStandaloneGraph {
return new TransectLineGraph(title);
}
public static Date calcAnnotationTime(String annotation, String timepattern){
String time = annotation.substring(0,annotation.indexOf(";"));
Date timeD = null;
try {
timeD = new SimpleDateFormat(timepattern).parse(time);
} catch (ParseException e) {
}
return timeD;
}
public static DefaultCategoryDataset orderByTime(DefaultCategoryDataset annotatedTimeChart, String timepattern){
DefaultCategoryDataset orderedChart = new DefaultCategoryDataset();
if (annotatedTimeChart==null)
return orderedChart;
List<Double> values = new ArrayList<Double>();
List<String> annotations= new ArrayList<String>();
List<Date> dates = new ArrayList<Date>();
int ncols = annotatedTimeChart.getColumnCount();
//suppose there is only one time series here
String rowkey = annotatedTimeChart.getRowKeys().get(0).toString();
for (int i=0;i<ncols ;i++){
String annotation = annotatedTimeChart.getColumnKey(i).toString();
double value = (Double)annotatedTimeChart.getValue(rowkey, annotation);
Date timeD = calcAnnotationTime(annotation, timepattern);
if (timeD!=null){
int ncolsOrdered = dates.size();
int bestidx =ncolsOrdered;
for (int j=0;j<ncolsOrdered;j++){
Date timeo = dates.get(j);
if (timeo.after(timeD)){
bestidx=j;
break;
}
}
values.add(bestidx, value);
annotations.add(bestidx, annotation);
dates.add(bestidx, timeD);
}
}
int nvals = values.size();
for (int i=0;i<nvals;i++){
orderedChart.addValue(values.get(i), rowkey, annotations.get(i));
}
return orderedChart;
}
static class CustomXAxis extends CategoryAxis {
DefaultCategoryDataset dataset;

View File

@ -4,10 +4,13 @@ import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
import org.gcube.dataanalysis.ecoengine.transducers.charts.QuantitiesAttributesChartsTransducerer;
import org.gcube.dataanalysis.ecoengine.transducers.charts.TimeSeriesChartsTransducerer;
import org.junit.Test;
public class ChartsTests {
public static void main(String[] args) throws Exception{
@Test
public void testSmallGeneric() throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
@ -19,19 +22,127 @@ public class ChartsTests {
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "hspen_mini");
// config.setParam("Attributes", "speciesid#lifestage#faoareas");
config.setParam("Attributes", "speciesid#lifestage#faoareas");
config.setParam("Quantities", "depthmax#speccode");
config.setGcubeScope("/gcube/devsec/devVRE");
QuantitiesAttributesChartsTransducerer cscreator = new QuantitiesAttributesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
public static void main1(String[] args) throws Exception{
@Test
public void testLargeGeneric() throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "generic_id6ef3e4fa_6a06_4df1_9445_553f2e918102");
config.setParam("Attributes", "long#lat");
config.setParam("Quantities", "long");
config.setGcubeScope("/gcube/devsec/devVRE");
QuantitiesAttributesChartsTransducerer cscreator = new QuantitiesAttributesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
@Test
public void testStrangeGeneric() throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "generic_id0746f5ab_fb3e_4848_97cd_43f46ae57ac1");
config.setParam("Attributes", "time#quantity");
config.setParam("Quantities", "quantity");
config.setGcubeScope("/gcube/devsec/devVRE");
QuantitiesAttributesChartsTransducerer cscreator = new QuantitiesAttributesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
@Test
public void testLonLatDataset() throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "csq_84e9302c161243a3b29f3eff9c392d3e");
config.setParam("Attributes", "field1");
config.setParam("Quantities", "field2");
config.setGcubeScope("/gcube/devsec/devVRE");
QuantitiesAttributesChartsTransducerer cscreator = new QuantitiesAttributesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
public static void main(String[] args) throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "generic_id0db6e87b_abd6_4dfc_aa05_208eab3df212");
config.setParam("Attributes", "decimallongitude#decimallatitude");
config.setParam("Quantities", "chlorophyll");
config.setGcubeScope("/gcube/devsec/devVRE");
QuantitiesAttributesChartsTransducerer cscreator = new QuantitiesAttributesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
public static void mainTimeSeriesMedium(String[] args) throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
@ -56,4 +167,86 @@ public class ChartsTests {
System.out.println("DONE! "+cscreator.getOutput());
}
public static void main1(String[] args) throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "generic_idc3f49110_995b_45cd_9846_240f25c136be");
// config.setParam("Attributes", "decimallatitude#decimallongitude#basisofrecord");
// config.setParam("Attributes", "");
config.setParam("Quantities", "maxdepth");
config.setParam("Time", "eventdate");
config.setGcubeScope("/gcube/devsec/devVRE");
TimeSeriesChartsTransducerer cscreator = new TimeSeriesChartsTransducerer();
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
@Test
public void testTimeSeriesSuperposed() throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "generic_id3249137c_1559_438c_857b_29942cb13118");
config.setParam("Attributes", "latdecdeg#longdecdeg");
config.setParam("Quantities", "specific_a");
config.setParam("Time", "begperiod");
config.setGcubeScope("/gcube/devsec/devVRE");
TimeSeriesChartsTransducerer cscreator = new TimeSeriesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
@Test
public void testTimeSeriesLongFAO() throws Exception{
AnalysisLogger.setLogger("./cfg/" + AlgorithmConfiguration.defaultLoggerFile);
AlgorithmConfiguration config = new AlgorithmConfiguration();
config.setConfigPath("./cfg/");
config.setPersistencePath("./");
config.setParam("DatabaseUserName", "utente");
config.setParam("DatabasePassword", "d4science");
config.setParam("DatabaseURL", "jdbc:postgresql://statistical-manager.d.d4science.research-infrastructures.eu/testdb");
config.setParam("DatabaseDriver", "org.postgresql.Driver");
config.setParam("InputTable", "generic_id0746f5ab_fb3e_4848_97cd_43f46ae57ac1");
config.setParam("Attributes", "catch#country#suggested_country");
config.setParam("Quantities", "quantity");
config.setParam("Time", "time");
config.setGcubeScope("/gcube/devsec/devVRE");
TimeSeriesChartsTransducerer cscreator = new TimeSeriesChartsTransducerer();
cscreator.displaycharts=true;
cscreator.setConfiguration(config);
cscreator.compute();
System.out.println("DONE! "+cscreator.getOutput());
}
}

View File

@ -1,12 +1,12 @@
package org.gcube.dataanalysis.ecoengine.transducers.charts;
import java.awt.Image;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import org.gcube.contentmanagement.graphtools.data.conversions.ImageTools;
import org.gcube.contentmanagement.lexicalmatcher.analysis.core.LexicalEngineConfiguration;
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
import org.gcube.dataanalysis.ecoengine.configuration.AlgorithmConfiguration;
@ -18,29 +18,39 @@ import org.gcube.dataanalysis.ecoengine.utils.DatabaseFactory;
import org.gcube.dataanalysis.ecoengine.utils.DatabaseUtils;
import org.gcube.dataanalysis.ecoengine.utils.IOHelper;
import org.hibernate.SessionFactory;
import org.jfree.chart.JFreeChart;
public abstract class AbstractChartsProducer extends StandardLocalExternalAlgorithm {
static String inputTableParameter = "InputTable";
static String attributesParameter = "Attributes";
static String quantitiesParameter = "Quantities";
static String timeParameter = "Time";
public HashMap<String, Image> producedImages = new HashMap<String, Image>();
public boolean displaycharts = true;
static int maxSeries = 10;
protected static String inputTableParameter = "InputTable";
protected static String attributesParameter = "Attributes";
protected static String quantitiesParameter = "Quantities";
protected static String timeParameter = "Time";
protected static String topElementsNumber = "TopElementsNumber";
public LinkedHashMap<String, Image> producedImages = new LinkedHashMap<String, Image>();
public LinkedHashMap<String, File> producedFiles = new LinkedHashMap<String, File>();
public boolean displaycharts = false;
protected int maxElements = 10;
SessionFactory connection = null;
protected SessionFactory connection = null;
@Override
protected abstract void setInputParameters();
@Override
public StatisticalType getOutput() {
PrimitiveType images = new PrimitiveType(HashMap.class.getName(), producedImages, PrimitiveTypes.IMAGES, "images", "Charts");
LinkedHashMap<String, StatisticalType> outputmap = new LinkedHashMap<String, StatisticalType>();
outputmap.put("Images", images);
if (producedImages.size()>0){
PrimitiveType images = new PrimitiveType(HashMap.class.getName(), producedImages, PrimitiveTypes.IMAGES, "images", "Charts");
outputmap.put("Images", images);
}
if (producedFiles.size()>0){
for (String file:producedFiles.keySet()){
File f = producedFiles.get(file);
PrimitiveType p = new PrimitiveType(File.class.getName(), f, PrimitiveTypes.FILE, f.getName(), file);
outputmap.put(file, p);
}
}
PrimitiveType output = new PrimitiveType(HashMap.class.getName(), outputmap, PrimitiveTypes.MAP, "ResultsMap", "Results Map");
return output;
}
@ -64,7 +74,10 @@ public abstract class AbstractChartsProducer extends StandardLocalExternalAlgori
public String[] getQuantities() {
String quantitieS = IOHelper.getInputParameter(config, quantitiesParameter);
String[] quantities = quantitieS.split(AlgorithmConfiguration.getListSeparator());
String[] quantities = {""};
if (quantitieS!=null){
quantities = quantitieS.split(AlgorithmConfiguration.getListSeparator());
}
return quantities;
}
@ -76,24 +89,26 @@ public abstract class AbstractChartsProducer extends StandardLocalExternalAlgori
public String InfoRetrievalQuery(String table, String[] dimensions, String quantity,String time) {
if (time!=null){
if (dimensions!=null && dimensions.length>0)
return "select * from (select distinct " + Arrays.toString(dimensions).replace("[", "").replace("]", "") + " , " + quantity +","+time+" from "+table+" order by " + quantity + " limit " + maxSeries+") as a order by "+time;
return "select distinct " + Arrays.toString(dimensions).replace("[", "").replace("]", "") + " , " + quantity +" as qa123a,"+time+" as timea123a from "+table+" order by timea123a";
else
return "select * from (select distinct " +quantity +","+time+" from "+table+" order by " + quantity + " limit " + maxSeries+") as a order by "+time;
return "select distinct " +quantity +","+time+" from "+table+" order by "+time;
}
else{
if (dimensions!=null && dimensions.length>0)
return "select distinct " + Arrays.toString(dimensions).replace("[", "").replace("]", "") + " , " + quantity +" from "+table+" order by " + quantity + " limit " + maxSeries;
try{maxElements = Integer.parseInt(IOHelper.getInputParameter(config, topElementsNumber));}catch(Exception e){}
if (dimensions!=null && dimensions.length>0){
String field = Arrays.toString(dimensions).replace("[", "").replace("]", "");
return "select distinct " +field + " , sum(CAST (" + quantity +" as real)) as qa123a from "+table+" where CAST("+quantity+" as character varying) <>'' "+" group by "+field+" order by qa123a DESC limit " + maxElements;
}
else
return "select distinct row_number() over(), " + quantity +" from "+table+" order by " + quantity + " limit " + maxSeries;
return "select distinct row_number() over(), " + quantity +" from "+table+" order by " + quantity + " DESC limit " + maxElements;
}
}
@Override
protected void process() throws Exception {
status = 0;
status = 10;
AnalysisLogger.setLogger(config.getConfigPath() + AlgorithmConfiguration.defaultLoggerFile);
long t0 = System.currentTimeMillis();
try {
AnalysisLogger.getLogger().debug("ChartsProducer started");
String driver = config.getParam("DatabaseDriver");
@ -118,33 +133,51 @@ public abstract class AbstractChartsProducer extends StandardLocalExternalAlgori
String[] quantities = getQuantities();
String time = getTimeDimension();
//one quantity for each chart
//one quantity for each chart
boolean noCharts = true;
status = 40;
float step = (90-status)/(float)quantities.length;
for (String quantity : quantities) {
//produce chart with dimensions,quantity, time
String query = InfoRetrievalQuery(table,dimensions,quantity,time);
AnalysisLogger.getLogger().debug("ChartsProducer: Query for retrieving information "+query);
List<Object> values = DatabaseFactory.executeSQLQuery(query, connection);
JFreeChart[] charts= createCharts(dimensions,quantity,time,values,displaycharts);
for (JFreeChart chart:charts){
if (values==null)
throw new Exception("There are issued in managing selected attributes and quantities");
else if (values.size()==0)
throw new Exception("There are no viable values to be processed");
LinkedHashMap<String,Object> charts= createCharts(dimensions,quantity,time,values,displaycharts);
for (String chartName:charts.keySet()){
Object chart = charts.get(chartName);
if (chart!=null){
Image image= ImageTools.toImage(chart.createBufferedImage(680, 420));
producedImages.put("Charts focused on "+quantity, image);
noCharts=false;
//patch for current SM visualization
if (chart instanceof File)
producedFiles.put("Chart focused on "+quantity+" - "+chartName, (File)chart);
else
producedImages.put("Chart focused on "+quantity+" - "+chartName, (Image)chart);
}
}
status+=step;
}
if (noCharts)
throw new Exception("Error - no chart was produced because of incompatibility with the selected input parameters");
AnalysisLogger.getLogger().debug("ChartsProducer: finished");
} catch (Throwable e) {
e.printStackTrace();
throw new Exception(e.getMessage());
throw new Exception("Error during the computation: "+e.getMessage());
} finally {
shutdown();
status = 100;
}
}
public abstract JFreeChart[] createCharts(String[] dimensions,String quantity,String time,List<Object> rows, boolean displaychart);
public abstract LinkedHashMap<String,Object> createCharts(String[] dimensions,String quantity,String time,List<Object> rows, boolean displaychart);
@Override

View File

@ -1,8 +1,11 @@
package org.gcube.dataanalysis.ecoengine.transducers.charts;
import java.awt.Image;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.gcube.contentmanagement.graphtools.data.conversions.ImageTools;
import org.gcube.contentmanagement.graphtools.plotting.graphs.GaussianDistributionGraph;
import org.gcube.contentmanagement.graphtools.plotting.graphs.HistogramGraph;
import org.gcube.contentmanagement.graphtools.plotting.graphs.RadarGraph;
@ -15,7 +18,6 @@ import org.gcube.dataanalysis.ecoengine.datatypes.DatabaseType;
import org.gcube.dataanalysis.ecoengine.datatypes.InputTable;
import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.TableTemplates;
import org.gcube.dataanalysis.ecoengine.utils.IOHelper;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.function.NormalDistributionFunction2D;
import org.jfree.data.general.DatasetUtilities;
@ -24,7 +26,6 @@ import org.jfree.data.xy.XYSeriesCollection;
public class QuantitiesAttributesChartsTransducerer extends AbstractChartsProducer {
@Override
protected void setInputParameters() {
List<TableTemplates> templates = new ArrayList<TableTemplates>();
@ -33,6 +34,7 @@ public class QuantitiesAttributesChartsTransducerer extends AbstractChartsProduc
inputs.add(tinput);
ColumnTypesList p1 = new ColumnTypesList(inputTableParameter, attributesParameter, "The dimensions to consider in the charts", true);
ColumnTypesList p2 = new ColumnTypesList(inputTableParameter, quantitiesParameter, "The numeric quantities to visualize ", false);
IOHelper.addIntegerInput(inputs, topElementsNumber, "Max number of elements, with highest values, to visualize", "10");
inputs.add(p1);
inputs.add(p2);
@ -45,7 +47,7 @@ public class QuantitiesAttributesChartsTransducerer extends AbstractChartsProduc
}
@Override
public JFreeChart[] createCharts(String[] dimensions, String quantity, String time, List<Object> rows, boolean displaychart) {
public LinkedHashMap<String,Object> createCharts(String[] dimensions, String quantity, String time, List<Object> rows, boolean displaychart) {
if (dimensions==null)
dimensions=new String[0];
@ -74,8 +76,19 @@ public class QuantitiesAttributesChartsTransducerer extends AbstractChartsProduc
}
List<Object> meanvar = DatabaseFactory.executeSQLQuery("select avg("+quantity+"), variance("+quantity+") from "+IOHelper.getInputParameter(config, inputTableParameter), connection);
Object[] meanvarsrow = (Object[]) meanvar.get(0);
// List<Object> meanvar = DatabaseFactory.executeSQLQuery("select avg("+"( CAST ( " + quantity + " as real))"+"), variance("+"( CAST ( " + quantity + " as real))"+") from "+IOHelper.getInputParameter(config, inputTableParameter), connection);
String selectMeanVar = "select avg(( CAST ( "+quantity+" as real))), variance(( CAST ( "+quantity+" as real))) from (select "+quantity+" from "+IOHelper.getInputParameter(config, inputTableParameter)+" where "+quantity+" IS NOT NULL and CAST("+quantity+" as character varying) <> '' ) as a";
AnalysisLogger.getLogger().debug("QuantitiesAttributesCharts: select for mean and variance: "+selectMeanVar);
List<Object> meanvar = DatabaseFactory.executeSQLQuery(selectMeanVar, connection);
Object[] meanvarsrow = {0,0.1};
try{
meanvarsrow = (Object[]) meanvar.get(0);}catch(Exception e){
AnalysisLogger.getLogger().debug("QuantitiesAttributesCharts: cannot detect mean and variance for "+quantity);
}
double mean = MathFunctions.roundDecimal(Double.parseDouble(""+meanvarsrow[0]),2);
double variance = MathFunctions.roundDecimal(Math.sqrt(Double.parseDouble(""+meanvarsrow[1])),2);
@ -86,17 +99,17 @@ public class QuantitiesAttributesChartsTransducerer extends AbstractChartsProduc
XYSeriesCollection gaussianxyseriescollection = new XYSeriesCollection();
gaussianxyseriescollection .addSeries(gaussianxyseries);
JFreeChart charthisto = null;
JFreeChart chartscattering = null;
JFreeChart chartradar = null;
Image charthisto = null;
Image chartscattering = null;
Image chartradar = null;
if (dimensions.length>0){
charthisto = HistogramGraph.createStaticChart(datasetHisto);
chartscattering = ScatterGraphGeneric.createStaticChart(datasetHisto);
chartradar = RadarGraph.createStaticChart(datasetHisto);
charthisto = ImageTools.toImage(HistogramGraph.createStaticChart(datasetHisto).createBufferedImage(1200, 960));
chartscattering = ImageTools.toImage(ScatterGraphGeneric.createStaticChart(datasetHisto).createBufferedImage(1200, 960));
chartradar = ImageTools.toImage(RadarGraph.createStaticChart(datasetHisto).createBufferedImage(1200, 960));
}
JFreeChart chartgaussian = GaussianDistributionGraph.createStaticChart(gaussianxyseriescollection, mean, variance);
Image chartgaussian = ImageTools.toImage(GaussianDistributionGraph.createStaticChart(gaussianxyseriescollection, mean, variance).createBufferedImage(1200, 960));
if (displaychart){
HistogramGraph tsg = new HistogramGraph("QuantitiesAttributesHistogram");
@ -115,11 +128,12 @@ public class QuantitiesAttributesChartsTransducerer extends AbstractChartsProduc
}
JFreeChart [] charts = new JFreeChart[4];
charts [0] = charthisto;
charts [1] = chartscattering;
charts [2] = chartradar;
charts [3] = chartgaussian;
LinkedHashMap<String , Object> charts = new LinkedHashMap<String, Object>();
charts.put("Histogram of the top ten quantities over the dimensions", charthisto);
charts.put("Scattering of the top ten quantities over the dimensions", chartscattering);
charts.put("Radar chart of the top ten quantities over the dimensions", chartradar);
charts.put("Overall mean and standard deviation of the quantity", chartgaussian);
return charts;
}

View File

@ -1,57 +1,72 @@
package org.gcube.dataanalysis.ecoengine.transducers.charts;
import java.awt.Image;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import org.gcube.contentmanagement.graphtools.plotting.graphs.LineGraph;
import org.gcube.contentmanagement.graphtools.data.conversions.ImageTools;
import org.gcube.contentmanagement.graphtools.plotting.graphs.TimeSeriesGraph;
import org.gcube.contentmanagement.graphtools.plotting.graphs.TransectLineGraph;
import org.gcube.contentmanagement.graphtools.utils.DateGuesser;
import org.gcube.contentmanagement.lexicalmatcher.utils.AnalysisLogger;
import org.gcube.dataanalysis.ecoengine.datatypes.ColumnType;
import org.jfree.chart.JFreeChart;
import org.gcube.dataanalysis.ecoengine.datatypes.ColumnTypesList;
import org.gcube.dataanalysis.ecoengine.datatypes.DatabaseType;
import org.gcube.dataanalysis.ecoengine.datatypes.InputTable;
import org.gcube.dataanalysis.ecoengine.datatypes.enumtypes.TableTemplates;
import org.gcube.dataanalysis.ecoengine.utils.Operations;
import org.gcube.dataanalysis.ecoengine.utils.TimeAnalyzer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import com.sun.org.apache.bcel.internal.generic.LNEG;
import org.jfree.data.time.TimeSeriesDataItem;
public class TimeSeriesChartsTransducerer extends QuantitiesAttributesChartsTransducerer {
@Override
protected void setInputParameters() {
super.setInputParameters();
ColumnType p = new ColumnType(inputTableParameter, timeParameter, "The column containing time information", "year", false);
inputs.add(p);
List<TableTemplates> templates = new ArrayList<TableTemplates>();
templates.add(TableTemplates.GENERIC);
InputTable tinput = new InputTable(templates, inputTableParameter, "The input table");
inputs.add(tinput);
ColumnTypesList p1 = new ColumnTypesList(inputTableParameter, attributesParameter, "The dimensions to consider in the charts", true);
ColumnTypesList p2 = new ColumnTypesList(inputTableParameter, quantitiesParameter, "The numeric quantities to visualize ", false);
inputs.add(p1);
inputs.add(p2);
ColumnType p3 = new ColumnType(inputTableParameter, timeParameter, "The column containing time information", "year", false);
inputs.add(p3);
DatabaseType.addDefaultDBPars(inputs);
}
@Override
public String getDescription() {
return "An algorithm producing time series charts of attributes vs. quantities. Charts are displayed per quantity column and only the top ten quantities are reported.";
return "An algorithm producing time series charts of attributes vs. quantities. Charts are displayed per quantity column and superposing quantities are summed.";
}
String timepattern = "";
SimpleDateFormat formatter = null;
Date sampleTime = null;
protected String timepattern = "";
protected SimpleDateFormat formatter = null;
protected Date sampleTime = null;
protected int maxvisualizable = 100;
public Date getTime(String timel) {
timel = timel.replace("time:", "");
try {
if (formatter == null) {
timepattern = DateGuesser.getPattern(timel);
AnalysisLogger.getLogger().debug("Time pattern: " + timepattern);
TimeAnalyzer analyzer = new TimeAnalyzer();
sampleTime = analyzer.string2Date(timel);
timepattern = analyzer.getPattern();
AnalysisLogger.getLogger().debug("TimeSeriesChart: Time pattern: " + timepattern);
formatter = new SimpleDateFormat(timepattern);
sampleTime = formatter.parse(timel);
}
return formatter.parse(timel);
} catch (ParseException e) {
e.printStackTrace();
AnalysisLogger.getLogger().debug("Error parsing date " + timel + " using pattern " + timepattern);
return null;
}
}
@ -69,14 +84,16 @@ public class TimeSeriesChartsTransducerer extends QuantitiesAttributesChartsTran
}
@Override
public JFreeChart[] createCharts(String[] dimensions, String quantity, String time, List<Object> rows, boolean displaychart) {
public LinkedHashMap<String, Object> createCharts(String[] dimensions, String quantity, String time, List<Object> rows, boolean displaychart) {
if (dimensions==null)
if (dimensions == null)
dimensions = new String[0];
LinkedHashMap<String, Object> charts = new LinkedHashMap<String, Object>();
TimeSeriesCollection dataset = new TimeSeriesCollection();
TimeSeries series = null;
if (dimensions.length>0)
if (dimensions.length > 0)
series = new TimeSeries("Trend of " + quantity + " for " + Arrays.toString(dimensions).replace("[", "").replace("]", ""));
else
series = new TimeSeries("Trend of " + quantity);
@ -84,8 +101,19 @@ public class TimeSeriesChartsTransducerer extends QuantitiesAttributesChartsTran
DefaultCategoryDataset[] linedatasets = new DefaultCategoryDataset[dimensions.length];
for (Object row : rows) {
int nrows = rows.size();
int[] indicesToTake = null;
if (nrows > maxvisualizable)
indicesToTake = Operations.uniformIntegerSampling(0, nrows - 1, maxvisualizable);
else
indicesToTake = Operations.uniformIntegerSampling(0, nrows - 1, nrows);
AnalysisLogger.getLogger().debug("TimeSeriesChartsTransducerer: uniform sampling - taking " + indicesToTake.length + " over " + nrows);
for (int i = 0; i < indicesToTake.length; i++) {
Object row = rows.get(indicesToTake[i]);
Object[] array = (Object[]) row;
// AnalysisLogger.getLogger().debug("TimeSeriesChartsTransducerer: "+Arrays.toString(array));
Double q = null;
Date timeD = null;
String timel = "" + array[array.length - 1];
@ -93,45 +121,54 @@ public class TimeSeriesChartsTransducerer extends QuantitiesAttributesChartsTran
q = Double.parseDouble("" + array[array.length - 2]);
timeD = getTime(timel);
} catch (Exception e) {
AnalysisLogger.getLogger().debug("TimeSeriesChartsTransducerer: warning skipping value " + q + "," + timel);
}
if (q != null && timeD != null) {
FixedMillisecond ms = new FixedMillisecond(timeD);
series.add(ms, q);
TimeSeriesDataItem item = series.getDataItem(ms);
if (item != null) {
double prevquant = (Double) item.getValue();
q = prevquant + q;
AnalysisLogger.getLogger().debug("TimeSeriesChartsTransducerer: a previous quantity was found for time " + timel + " : " + prevquant + " setting to " + (prevquant + q));
item.setValue(q);
} else
series.add(ms, q);
for (int dimIdx=0;dimIdx<dimensions.length;dimIdx++) {
for (int dimIdx = 0; dimIdx < dimensions.length; dimIdx++) {
String dimensionValue = "";
if (array[dimIdx] != null)
dimensionValue = "" + array[dimIdx];
if (dimensionValue.length() > 0) {
DefaultCategoryDataset lineds = linedatasets[dimIdx];
if (lineds == null){
if (lineds == null) {
lineds = new DefaultCategoryDataset();
linedatasets[dimIdx]=lineds;
linedatasets[dimIdx] = lineds;
}
lineds.addValue(q, "singlets", timel + ";[" + dimensionValue + "]");
}
}
}
}
if (sampleTime != null) {
Image chartTS = ImageTools.toImage(TimeSeriesGraph.createStaticChart(dataset, getChartPattern(sampleTime), "Variation of " + quantity).createBufferedImage(1200, 960));
JFreeChart chartTS = TimeSeriesGraph.createStaticChart(dataset, getChartPattern(sampleTime), "Variations of " + quantity);
if (displaychart) {
TimeSeriesGraph tsg = new TimeSeriesGraph("Variations of " + quantity);
tsg.timeseriesformat = getChartPattern(sampleTime);
tsg.render(dataset);
for (int i = 0; i < dimensions.length; i++) {
TransectLineGraph tlg = new TransectLineGraph("Variations of " + dimensions[i]);
tlg.render(linedatasets[i]);
if (displaychart) {
TimeSeriesGraph tsg = new TimeSeriesGraph("Variation of " + quantity);
tsg.timeseriesformat = getChartPattern(sampleTime);
tsg.render(dataset);
for (int i = 0; i < dimensions.length; i++) {
TransectLineGraph tlg = new TransectLineGraph("Variation of " + dimensions[i]);
tlg.render(TransectLineGraph.orderByTime(linedatasets[i], timepattern));
}
}
}
JFreeChart[] charts = new JFreeChart[1 + dimensions.length];
charts[0] = chartTS;
for (int i = 0; i < dimensions.length; i++) {
JFreeChart linechartTS = LineGraph.createStaticChart(linedatasets[i], "Variations of " + dimensions[i]);
charts[i+1] = linechartTS;
charts.put("Time trend of " + quantity, chartTS);
for (int i = 0; i < dimensions.length; i++) {
Image linechartTS = ImageTools.toImage(TransectLineGraph.createStaticChart(TransectLineGraph.orderByTime(linedatasets[i], timepattern)).createBufferedImage(1200, 960));
charts.put("Annotated chart of " + quantity + " for " + dimensions[i], linechartTS);
}
}
return charts;
}

View File

@ -0,0 +1,191 @@
package org.gcube.dataanalysis.ecoengine.utils;
//
// GifSequenceWriter.java
//
// Created by Elliot Kroo on 2009-04-25.
//
// This work is licensed under the Creative Commons Attribution 3.0 Unported
// License. To view a copy of this license, visit
// http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative
// Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageOutputStream;
public class GifSequenceWriter {
protected ImageWriter gifWriter;
protected ImageWriteParam imageWriteParam;
protected IIOMetadata imageMetaData;
/**
* Creates a new GifSequenceWriter
*
* @param outputStream the ImageOutputStream to be written to
* @param imageType one of the imageTypes specified in BufferedImage
* @param timeBetweenFramesMS the time between frames in miliseconds
* @param loopContinuously wether the gif should loop repeatedly
* @throws IIOException if no gif ImageWriters are found
*
* @author Elliot Kroo (elliot[at]kroo[dot]net)
*/
public GifSequenceWriter(
ImageOutputStream outputStream,
int imageType,
int timeBetweenFramesMS,
boolean loopContinuously) throws IIOException, IOException {
// my method to create a writer
gifWriter = getWriter();
imageWriteParam = gifWriter.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier =
ImageTypeSpecifier.createFromBufferedImageType(imageType);
imageMetaData =
gifWriter.getDefaultImageMetadata(imageTypeSpecifier,
imageWriteParam);
String metaFormatName = imageMetaData.getNativeMetadataFormatName();
IIOMetadataNode root = (IIOMetadataNode)
imageMetaData.getAsTree(metaFormatName);
IIOMetadataNode graphicsControlExtensionNode = getNode(
root,
"GraphicControlExtension");
graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute(
"transparentColorFlag",
"FALSE");
graphicsControlExtensionNode.setAttribute(
"delayTime",
Integer.toString(timeBetweenFramesMS / 10));
graphicsControlExtensionNode.setAttribute(
"transparentColorIndex",
"0");
IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
commentsNode.setAttribute("CommentExtension", "Created by MAH");
IIOMetadataNode appEntensionsNode = getNode(
root,
"ApplicationExtensions");
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");
int loop = loopContinuously ? 0 : 1;
child.setUserObject(new byte[]{ 0x1, (byte) (loop & 0xFF), (byte)
((loop >> 8) & 0xFF)});
appEntensionsNode.appendChild(child);
imageMetaData.setFromTree(metaFormatName, root);
gifWriter.setOutput(outputStream);
gifWriter.prepareWriteSequence(null);
}
public void writeToSequence(RenderedImage img) throws IOException {
gifWriter.writeToSequence(
new IIOImage(
img,
null,
imageMetaData),
imageWriteParam);
}
/**
* Close this GifSequenceWriter object. This does not close the underlying
* stream, just finishes off the GIF.
*/
public void close() throws IOException {
gifWriter.endWriteSequence();
}
/**
* Returns the first available GIF ImageWriter using
* ImageIO.getImageWritersBySuffix("gif").
*
* @return a GIF ImageWriter object
* @throws IIOException if no GIF image writers are returned
*/
private static ImageWriter getWriter() throws IIOException {
Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix("gif");
if(!iter.hasNext()) {
throw new IIOException("No GIF Image Writers Exist");
} else {
return iter.next();
}
}
/**
* Returns an existing child node, or creates and returns a new child node (if
* the requested node does not exist).
*
* @param rootNode the <tt>IIOMetadataNode</tt> to search for the child node.
* @param nodeName the name of the child node.
*
* @return the child node, if found or a new node created with the given name.
*/
private static IIOMetadataNode getNode(
IIOMetadataNode rootNode,
String nodeName) {
int nNodes = rootNode.getLength();
for (int i = 0; i < nNodes; i++) {
if (rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName)
== 0) {
return((IIOMetadataNode) rootNode.item(i));
}
}
IIOMetadataNode node = new IIOMetadataNode(nodeName);
rootNode.appendChild(node);
return(node);
}
public static void writeGif(String outputgifpath, List<String> imagefilespaths, int secondsdelay) throws Exception {
// grab the output image type from the first image in the sequence
BufferedImage firstImage = ImageIO.read(new File(imagefilespaths.get(0)));
// create a new BufferedOutputStream with the last argument
ImageOutputStream output =
new FileImageOutputStream(new File(outputgifpath));
// create a gif sequence with the type of the first image, 1 second
// between frames, which loops continuously
GifSequenceWriter writer =
new GifSequenceWriter(output, firstImage.getType(), secondsdelay, false);
firstImage.flush();
// write out the first image to our sequence...
writer.writeToSequence(firstImage);
for(String image:imagefilespaths) {
BufferedImage nextImage = ImageIO.read(new File(image));
writer.writeToSequence(nextImage);
}
writer.close();
output.close();
}
}

View File

@ -348,7 +348,7 @@ public class Operations {
}
}
public static void main(String[] args) {
public static void main2(String[] args) {
/*
* System.out.println("numbers to take: " + calcNumOfRepresentativeElements(100, 100)); double[] interp = linearInterpolation(27.27, 28.28, 3); double[] parabinterp = parabolicInterpolation(1, 10, 9); System.out.println("");
*/
@ -402,4 +402,37 @@ public class Operations {
return chunksize;
}
public static double[] uniformSampling(double min, double max, int maxElementsToTake){
double step = (max-min)/(double)(maxElementsToTake-1);
double [] samples = new double [maxElementsToTake];
for (int i=0;i<samples.length;i++){
double value = min+i*step;
if (value>max)
value=max;
samples [i] = value;
}
return samples;
}
public static int[] uniformIntegerSampling(double min, double max, int maxElementsToTake){
double step = (max-min)/(double)(maxElementsToTake-1);
int [] samples = new int [maxElementsToTake];
for (int i=0;i<samples.length;i++){
double value = min+i*step;
if (value>max)
value=max;
samples [i] = (int)value;
}
return samples;
}
public static void main(String[] args) {
double [] samples = uniformSampling(0, 9, 10);
System.out.println("OK");
}
}

View File

@ -0,0 +1,48 @@
package org.gcube.dataanalysis.ecoengine.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.gcube.contentmanagement.graphtools.utils.DateGuesser;
public class TimeAnalyzer {
private String pattern = "";
public String getPattern(){
return pattern;
}
public Date string2Date(String time) {
try {
time = time.replace("time:", "");
String timepattern = DateGuesser.getPattern(time);
SimpleDateFormat sdf = new SimpleDateFormat(timepattern, Locale.ENGLISH);
Date timedate = (Date) sdf.parse(time);
if (timepattern.equals("s")) {
timepattern = "HH:mm:ss:SS";
sdf = new SimpleDateFormat(timepattern, Locale.ENGLISH);
timedate = (Date) sdf.parse(time);
}
pattern=timepattern;
return timedate;
} catch (Exception e) {
return new Date(System.currentTimeMillis());
}
}
public static int getTimeIndexInTimeRange(Date maxdate,Date mindate,Date currentdate, int chunks){
long timemax = maxdate.getTime();
long timemin = mindate.getTime();
long timecurr = currentdate.getTime();
return (int)Math.round((double)(timecurr-timemin)*(double)chunks/(double)(timemax-timemin));
}
}