Revision 177

tmp/org.txm.ca.core/src/org/txm/ca/core/chartsengine/jfreechart/themes/highcharts/chartcreators/JFCSingularValueChartCreator.java (revision 177)
1
package org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.chartcreators;
2

  
3
import org.jfree.chart.JFreeChart;
4
import org.jfree.chart.axis.NumberAxis;
5
import org.jfree.data.category.DefaultCategoryDataset;
6
import org.jfree.data.general.DatasetUtilities;
7
import org.txm.ca.core.functions.CA;
8
import org.txm.ca.core.messages.CACoreMessages;
9
import org.txm.chartsengine.jfreechart.core.JFCChartCreator;
10
import org.txm.chartsengine.jfreechart.core.renderers.interfaces.IItemSelectionRenderer;
11
import org.txm.chartsengine.jfreechart.core.themes.base.ExtendedNumberAxis;
12
import org.txm.stat.StatException;
13
import org.txm.utils.logger.Log;
14

  
15
/**
16
 * JFC progression chart creator.
17
 * 
18
 * @author sjacquot
19
 *
20
 */
21
public class JFCSingularValueChartCreator extends JFCChartCreator {
22

  
23
	public JFCSingularValueChartCreator() {
24
		// TODO Auto-generated constructor stub
25
	}
26

  
27

  
28

  
29

  
30
	@Override
31
	public Object createChart(Object resultData, String preferencesNode) {
32
		
33
		
34
		CA ca = (CA) resultData;
35

  
36
		JFreeChart chart = null;
37

  
38
		try {
39
			// Creating the data set from the CA result
40
			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
41
			double[] singularValues = ca.getValeursPropres();
42

  
43
			for(int i = 0; i < singularValues.length; i++) {
44
				dataset.setValue(singularValues[i], CACoreMessages.ChartsEngine_CA_SINGULAR_VALUES_TOOLTIP_Y_LABEL, CACoreMessages.ChartsEngine_CA_SINGULAR_VALUES_X_LABELS_PREFIX + String.valueOf(i + 1));
45
			}
46

  
47
			// Create the chart
48
			chart = this.getChartsEngine().createCategoryBarChart(dataset, CACoreMessages.ChartsEngine_CA_SINGULAR_VALUES_TITLE, CACoreMessages.ChartsEngine_CA_SINGULAR_VALUES_X_AXIS_LABEL, CACoreMessages.ChartsEngine_CA_SINGULAR_VALUES_Y_AXIS_LABEL, false, false, false);
49

  
50
			// Custom renderer
51
			chart.getCategoryPlot().setRenderer(this.getChartsEngine().getTheme().createCASingularValuesRenderer());
52
	        ((IItemSelectionRenderer) chart.getCategoryPlot().getRenderer()).getItemsSelector().setResultData(ca);
53

  
54
	        // Custom range axis for ticks drawing options
55
	        chart.getCategoryPlot().setRangeAxis(new ExtendedNumberAxis((NumberAxis) chart.getCategoryPlot().getRangeAxis(), false, true, 0, DatasetUtilities.findMaximumRangeValue(chart.getCategoryPlot().getDataset()).doubleValue()));
56

  
57
		}
58
		catch(StatException e) {
59
			Log.severe(CACoreMessages.ChartsEngine_CA_SINGULAR_VALUES_CANT_CREATE_CHART + e);
60
		}
61

  
62

  
63
		return chart;
64
	}
65

  
66
	
67
	@Override
68
	public Class getResultDataClass() {
69
		return CA.class;
70
	}
71

  
72

  
73
	
74

  
75
}
0 76

  
tmp/org.txm.ca.core/src/org/txm/ca/core/chartsengine/jfreechart/themes/highcharts/chartcreators/JFCCAChartCreator.java (revision 177)
1
package org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.chartcreators;
2

  
3
import java.awt.BasicStroke;
4
import java.awt.Color;
5
import java.text.DecimalFormat;
6
import java.util.ArrayList;
7

  
8
import org.jfree.chart.ChartFactory;
9
import org.jfree.chart.JFreeChart;
10
import org.jfree.chart.annotations.XYAnnotation;
11
import org.jfree.chart.annotations.XYLineAnnotation;
12
import org.jfree.chart.labels.ItemLabelAnchor;
13
import org.jfree.chart.labels.ItemLabelPosition;
14
import org.jfree.chart.plot.PlotOrientation;
15
import org.jfree.chart.plot.XYPlot;
16
import org.jfree.chart.renderer.xy.XYItemRenderer;
17
import org.jfree.chart.title.LegendTitle;
18
import org.jfree.ui.TextAnchor;
19
import org.txm.ca.core.chartsengine.base.CAChartCreator;
20
import org.txm.ca.core.chartsengine.base.Utils;
21
import org.txm.ca.core.chartsengine.jfreechart.datasets.FCAXYDataset;
22
import org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.renderers.FCAItemSelectionRenderer;
23
import org.txm.ca.core.functions.CA;
24
import org.txm.ca.core.messages.CACoreMessages;
25
import org.txm.ca.core.preferences.CAPreferences;
26
import org.txm.chartsengine.core.preferences.ChartsEnginePreferences;
27
import org.txm.chartsengine.jfreechart.core.JFCChartCreator;
28
import org.txm.chartsengine.jfreechart.core.renderers.MultipleItemsSelector;
29
import org.txm.chartsengine.jfreechart.core.themes.base.BlockRoundBorder;
30
import org.txm.core.preferences.TXMPreferences;
31
import org.txm.stat.StatException;
32
import org.txm.utils.logger.Log;
33

  
34
/**
35
 * JFC progression chart creator.
36
 * 
37
 * @author sjacquot
38
 *
39
 */
40
public class JFCCAChartCreator extends JFCChartCreator implements CAChartCreator {
41

  
42
	public JFCCAChartCreator() {
43
		// TODO Auto-generated constructor stub
44
	}
45

  
46
	
47
	/**
48
	 * Add some borders to the limits of the specified XY plot.
49
	 * @param plot
50
	 */
51
	public void createCAFactorialMapChartLimitsBorder(JFreeChart chart)	{
52

  
53
		XYPlot plot = chart.getXYPlot();
54

  
55
		// Remove all existent annotations
56
		for(int i = plot.getAnnotations().size() - 1; i >= 0; i--) {
57
			plot.removeAnnotation((XYAnnotation) plot.getAnnotations().get(i));
58
		}
59

  
60

  
61
        // Gets the extreme coordinates values
62
		double minX = 0, maxX = 0, minY = 0, maxY = 0;
63

  
64
		// FIXME: new version
65
//		minX = plot.getDataRange(plot.getDomainAxis()).getLowerBound();
66
//		maxX = plot.getDataRange(plot.getDomainAxis()).getUpperBound();
67
//
68
//		minY = plot.getDataRange(plot.getRangeAxis()).getLowerBound();
69
//		maxY = plot.getDataRange(plot.getRangeAxis()).getUpperBound();
70

  
71
		// FIXME: old version, to remove when new version will be validated
72
		// Rows
73
		if(plot.getRenderer().isSeriesVisible(0))	{
74
			minX = ((FCAXYDataset)plot.getDataset()).getMinX(0);
75
		}
76
		// Cols
77
		if(plot.getRenderer().isSeriesVisible(1))	{
78
			double tmpMinX = ((FCAXYDataset)plot.getDataset()).getMinX(1);
79
			if(tmpMinX < minX)	{
80
				minX = tmpMinX;
81
			}
82
		}
83

  
84
		// Rows
85
		if(plot.getRenderer().isSeriesVisible(0))	{
86
			maxX = ((FCAXYDataset)plot.getDataset()).getMaxX(0);
87
		}
88
		// Cols
89
		if(plot.getRenderer().isSeriesVisible(1))	{
90
			double tmpMaxX = ((FCAXYDataset)plot.getDataset()).getMaxX(1);
91
			if(tmpMaxX > maxX)	{
92
				maxX = tmpMaxX;
93
			}
94
		}
95

  
96
		// Rows
97
		if(plot.getRenderer().isSeriesVisible(0))	{
98
			minY = ((FCAXYDataset)plot.getDataset()).getMinY(0);
99
		}
100
		// Cols
101
		if(plot.getRenderer().isSeriesVisible(1))	{
102
			double tmpMinY = ((FCAXYDataset)plot.getDataset()).getMinY(1);
103
			if(tmpMinY < minY)	{
104
				minY = tmpMinY;
105
			}
106
		}
107

  
108
		// Rows
109
		if(plot.getRenderer().isSeriesVisible(0))	{
110
			maxY = ((FCAXYDataset)plot.getDataset()).getMaxY(0);
111
		}
112
		// Cols
113
		if(plot.getRenderer().isSeriesVisible(1))	{
114
			double tmpMaxY = ((FCAXYDataset)plot.getDataset()).getMaxY(1);
115
			if(tmpMaxY > maxY)	{
116
				maxY = tmpMaxY;
117
			}
118
		}
119

  
120
		// Add some margins to the border
121
		// FIXME : to compute according to the real series shape dimensions
122
		// The code below doesn't work
123
//		double shapeHalfWidth = chart.getXYPlot().getRenderer().getSeriesShape(0).getBounds2D().getWidth() / 2;
124
		double shapeHalfWidth = 0.02;
125
		minX -= shapeHalfWidth;
126
		maxX += shapeHalfWidth;
127
		minY -= shapeHalfWidth;
128
		maxY += shapeHalfWidth;
129

  
130

  
131
		// Create the border
132
		BasicStroke dashedStroke = new BasicStroke(0.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1f, new float[] {2f}, 0f);
133
		XYLineAnnotation annotation;
134
		Color borderColor = Color.GRAY;
135

  
136
		// Left border
137
		annotation = new XYLineAnnotation(minX, minY, minX, maxY, dashedStroke, borderColor);
138
        plot.addAnnotation(annotation);
139

  
140
        // Right border
141
		annotation = new XYLineAnnotation(maxX, minY, maxX, maxY, dashedStroke, borderColor);
142
        plot.addAnnotation(annotation);
143

  
144
		// Bottom border
145
		annotation = new XYLineAnnotation(minX, minY, maxX, minY, dashedStroke, borderColor);
146
        plot.addAnnotation(annotation);
147

  
148
        // Top border
149
		annotation = new XYLineAnnotation(minX, maxY, maxX, maxY, dashedStroke, borderColor);
150
        plot.addAnnotation(annotation);
151

  
152
	}
153

  
154

  
155
	@Override
156
	public void updateChartCAFactorialMapHighlightPoints(Object chart, boolean rows, String[] labels) {
157

  
158
		MultipleItemsSelector selector = (MultipleItemsSelector) ((FCAItemSelectionRenderer)((JFreeChart) chart).getXYPlot().getRenderer()).getItemsSelector();
159

  
160
		// Rows
161
		int series = 0;
162
		// Columns
163
		if(!rows)	{
164
			series = 1;
165
		}
166
		selector.removeAllSelectedItems(series);
167
		int[] items = ((FCAXYDataset)((JFreeChart) chart).getXYPlot().getDataset()).getLabelIndices(series, labels);
168

  
169
		for(int i = 0; i < items.length; i++) {
170
			selector.addSelectedItem(series, items[i]);
171
		}
172

  
173
		//((JFreeChart) chart).setNotify(true);
174
	}
175

  
176

  
177
	@Override
178
	public void updateChartCAFactorialMapSetDimensions(Object chart, CA ca, int dimension1, int dimension2)	{
179

  
180
		 // Modify data set
181
		 ((FCAXYDataset) ((JFreeChart) chart).getXYPlot().getDataset()).setAxis1(dimension1);
182
		 ((FCAXYDataset) ((JFreeChart) chart).getXYPlot().getDataset()).setAxis2(dimension2);
183

  
184
		 // Update axis labels
185
		 // FIXME : create a method in CA to directly get a singular value as percent ?
186
		 try {
187
			 double sinuglarValuesSum = ca.getValeursPropresSum();
188
			 DecimalFormat f = new DecimalFormat("###.00"); //$NON-NLS-1$
189
			 ((JFreeChart) chart).getXYPlot().getDomainAxis().setLabel(CACoreMessages.ChartsEngine_CA_FACTORIAL_MAP_AXIS_LABEL_PREFIX + " " + dimension1 + " (" + f.format(100 * ca.getValeursPropres()[dimension1 - 1] / sinuglarValuesSum) + "%)");
190
			 ((JFreeChart) chart).getXYPlot().getRangeAxis().setLabel(CACoreMessages.ChartsEngine_CA_FACTORIAL_MAP_AXIS_LABEL_PREFIX + " " + dimension2 + " (" + f.format(100 * ca.getValeursPropres()[dimension2 - 1] / sinuglarValuesSum) + "%)");
191

  
192
			 // Refresh data set
193
			 // FIXME : any way to fire a data set event rather than reassign the same data set?
194
			 ((JFreeChart) chart).getXYPlot().setDataset(((JFreeChart) chart).getXYPlot().getDataset());
195
			// the code below doesn't neither center the view nor update the axes ticks of the new chart, continue tests
196
			//((JFreeChart) chart).setNotify(true);
197

  
198

  
199
			// Update the limits border
200
			this.createCAFactorialMapChartLimitsBorder((JFreeChart) chart);
201

  
202
		}
203
		catch(StatException e) {
204
			// TODO Auto-generated catch block
205
			e.printStackTrace();
206
		}
207
	 }
208

  
209

  
210
	
211

  
212
	@Override
213
	public void updateChart(Object chart, Object resultData, String preferencesNode) {
214

  
215

  
216
		FCAItemSelectionRenderer renderer = (FCAItemSelectionRenderer) ((JFreeChart)chart).getXYPlot().getRenderer(); 
217
   	 	XYPlot plot = ((JFreeChart)chart).getXYPlot();
218
		
219
		
220
		renderer.setSeriesVisible(0, TXMPreferences.getBoolean(preferencesNode, resultData, CAPreferences.SHOW_VARIABLES));
221
		renderer.setSeriesVisible(1, TXMPreferences.getBoolean(preferencesNode, resultData, CAPreferences.SHOW_INDIVIDUALS));
222
		
223
		// Create the limits border
224
		this.createCAFactorialMapChartLimitsBorder((JFreeChart) chart);
225

  
226
		this.updateChartCAFactorialMapSetDimensions(chart, (CA) resultData,
227
				TXMPreferences.getInt(preferencesNode, resultData, CAPreferences.FIRST_DIMENSION),
228
				TXMPreferences.getInt(preferencesNode, resultData, CAPreferences.SECOND_DIMENSION));
229
		
230

  
231
		super.updateChart(chart, resultData, preferencesNode);
232

  
233
		
234
    	((FCAItemSelectionRenderer)renderer).setBaseLinesVisible(false);
235
    	renderer.setBaseOutlinePaint(Color.decode("#666666"));
236

  
237
    	// Labels position
238
    	ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1, TextAnchor.BOTTOM_CENTER, TextAnchor.CENTER, 0.0);
239
    	renderer.setBasePositiveItemLabelPosition(position);
240
    	renderer.setBaseNegativeItemLabelPosition(position);
241

  
242
    	// Zero base lines
243
		plot.setDomainZeroBaselineVisible(true);
244
		plot.setRangeZeroBaselineVisible(true);
245

  
246
    	// Items colors (Highcharts color codes)
247
        Color blue = new Color(47, 126, 216, 90);
248
        renderer.setSeriesPaint(0, blue);
249

  
250
        Color red = new Color(255, 0, 0, 90);
251
        renderer.setSeriesPaint(1, red);
252

  
253
        // Legends
254
        LegendTitle legendTitle = ((JFreeChart) chart).getLegend(0);
255
    	if(legendTitle != null)	{
256
    		legendTitle.setFrame(new BlockRoundBorder(Color.GRAY));
257
    	}
258

  
259
    	
260

  
261
	}
262

  
263

  
264
	
265
	@Override
266
	public JFreeChart createChart(Object resultData, String preferencesNode) {
267

  
268
		
269
		CA ca = (CA) resultData;
270
		
271
		// parameters
272
//		boolean monochrome = (TXMPreferences.getInt(preferencesNode, resultData, ChartsEnginePreferences.RENDERING_COLORS_MODE, ChartsEnginePreferences.PREFERENCES_NODE)
273
//				== ChartsEngine.RENDERING_MONOCHROME_MODE);
274
//		boolean monostyle = TXMPreferences.getBoolean(preferencesNode, resultData, CAPreferences.CHART_MONO_STYLE);
275
//		boolean cumulative = TXMPreferences.getBoolean(preferencesNode, resultData, CAPreferences.CHART_CUMULATIVE);
276
		
277
		
278
		JFreeChart chart  = null;
279

  
280
		try {
281
			FCAXYDataset dataset = new FCAXYDataset(ca);
282

  
283
//			DecimalFormat f = new DecimalFormat("###.00"); //$NON-NLS-1$
284
//			double singularValuesSum = ca.getValeursPropresSum();
285
//
286
//			String percent1 = f.format(100 * ca.getValeursPropres()[ca.getFirstDimension() - 1] / singularValuesSum);
287
//			String xAxisLabel = CACoreMessages.ChartsEngine_CA_FACTORIAL_MAP_AXIS_LABEL_PREFIX + " " + ca.getFirstDimension() + " (" + percent1 + "%)";
288
//			String percent2 = f.format(100 * ca.getValeursPropres()[ca.getSecondDimension() - 1] / singularValuesSum);
289
//			String yAxisLabel = CACoreMessages.ChartsEngine_CA_FACTORIAL_MAP_AXIS_LABEL_PREFIX  + " " + ca.getSecondDimension() + " (" + percent2 + "%)";
290
			
291
			
292
			chart = ChartFactory.createScatterPlot(Utils.createCAFactorialMapChartTitle(ca), "", "", dataset, PlotOrientation.VERTICAL, TXMPreferences.getBoolean(CAPreferences.PREFERENCES_NODE, ChartsEnginePreferences.SHOW_LEGEND), false, false);
293

  
294
			// Custom renderer
295
			chart.getXYPlot().setRenderer(this.getChartsEngine().getTheme().createFCARenderer());
296

  
297

  
298
		}
299
		catch(StatException e) {
300
			Log.severe("Can't create CA factorial map scatter plot" + e);
301
		}
302

  
303

  
304
		return chart;		
305
		
306
	}
307

  
308
	@Override
309
	public ArrayList<String> getCAFactorialMapChartSelectedPoints(Object chart, int series) {
310

  
311
		MultipleItemsSelector selector = (MultipleItemsSelector) ((FCAItemSelectionRenderer)((JFreeChart) chart).getXYPlot().getRenderer()).getItemsSelector();
312
		ArrayList<String> pointLabels = new ArrayList<String>(selector.getSelectedItemsCount(series));
313

  
314
		if(selector.getSelectedItemsCount(series) > 0)	{
315

  
316
			FCAXYDataset dataset = (FCAXYDataset) ((JFreeChart) chart).getXYPlot().getDataset();
317
			int[] selectedItems = selector.getSelectedItems(series);
318

  
319
			for(int i = 0; i < selectedItems.length; i++) {
320
				pointLabels.add(dataset.getLabel(series, selectedItems[i]));
321
			}
322
		}
323
		return pointLabels;
324
	}
325
	
326

  
327

  
328

  
329
	@Override
330
	public void updateChartCAFactorialMapSetLabelItemsSelectionOrder(Object chart, String[] rowLabels, String[] colLabels) {
331
		
332
		MultipleItemsSelector selector = (MultipleItemsSelector) ((FCAItemSelectionRenderer)((JFreeChart) chart).getXYPlot().getRenderer()).getItemsSelector();
333
		selector.setCyclicItemsOrder(selector.getItemsAndSeriesOrderedByLabels((FCAXYDataset)((JFreeChart) chart).getXYPlot().getDataset(), rowLabels, colLabels)); 
334
	}
335

  
336

  
337
	@Override
338
	public Class getResultDataClass() {
339
		return CA.class;
340
	}
341

  
342

  
343
	
344

  
345
}
0 346

  

Also available in: Unified diff