Révision 3555

TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/export/office/SetOfficeMacro.groovy (revision 3555)
1
// STANDARD DECLARATIONS
2
package org.txm.macro.office
3

  
4
import org.kohsuke.args4j.*
5
import groovy.transform.Field
6
import org.txm.rcp.swt.widget.parameters.*
7

  
8
// BEGINNING OF PARAMETERS
9

  
10
@Field @Option(name="office_path", usage="Path to LibreOffice or OpenOffice installation directory", widget="Folder", required=false, def="libreoffice or openoffice install directory")
11
def office_path
12

  
13
// Open the parameters input dialog box
14
if (!ParametersDialog.open(this)) return;
15

  
16
// END OF PARAMETERS
17

  
18
if (office_path == null) {
19
	println "No path to office directory given."
20
	return
21
}
22

  
23
if (!office_path.exists()) {
24
	println "'$office_path' directory not found."
25
	return
26
}
27

  
28
if (!office_path.isDirectory()) {
29
	println "'$office_path' exists but is not a directory."
30
	return
31
}
32

  
33
if (!office_path.canExecute()) {
34
	println "'$office_path' exists but has not sufficent rights to be used."
35
	return
36
}
37

  
38
def old = System.getProperty("office.home")
39
System.setProperty("office.home", office_path.getAbsolutePath())
40
println "Office path set to '"+System.getProperty("office.home")+"'."
41
if (old != null) {
42
	println "	Previous path was '${old}'."
43
}
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/export/office/MergeExcelDirMacro.groovy (revision 3555)
1
// Copyright © 2019 ENS de Lyon, CNRS, University of Franche-Comté
2
// @author mdecorde
3
// @author sheiden
4

  
5
package org.txm.macro.office
6

  
7
import org.kohsuke.args4j.*
8
import groovy.transform.Field
9
import java.nio.charset.Charset
10
import org.txm.rcpapplication.swt.widget.parameters.*
11
import org.txm.utils.*
12
import javax.xml.stream.*
13
import java.net.URL
14

  
15
import org.apache.poi.ss.usermodel.*
16
import org.apache.poi.hssf.usermodel.*
17
import org.apache.poi.xssf.usermodel.*
18
import org.apache.poi.ss.util.*
19

  
20
@Field @Option(name="inputDirectory", usage="dossier des fichiers Excel à fusionner", widget="Folder", required=true, def="")
21
def inputDirectory
22

  
23
@Field @Option(name="outputFile", usage="output file", widget="FileSave", required=true, def="")
24
def outputFile
25

  
26
@Field @Option(name="sheetName", usage="sheet name (if no name is given the first sheet will be used)", widget="String", required=false, def="")
27
def sheetName
28

  
29
@Field @Option(name="columnList", usage="list of columns to extract, separated by comma", widget="String", required=false, def="")
30
def columnList
31

  
32
@Field @Option(name="multipleValues", usage="list of columns with multiple values, separated by comma", widget="String", required=false, def="")
33
def multipleValues
34

  
35
@Field @Option(name="normalizeIdentifiers", usage="normalize column names to simple lower case letters", widget="Boolean", required=true, def="true")
36
def normalizeIdentifiers
37

  
38
def stringToIdent = { str -> org.txm.utils.AsciiUtils.buildAttributeId(org.txm.utils.AsciiUtils.convertNonAscii(str)).toLowerCase() }
39

  
40
if (!ParametersDialog.open(this)) return false
41

  
42
if (!inputDirectory.exists()) {
43
	println "** $scriptName: no '"+inputDirectory.name+"' directory found. Aborting."
44
	return false
45
}
46

  
47
if (!inputDirectory.canRead()) {
48
	println "** $scriptName: '"+inputDirectory.name+"' directory not readable. Aborting."
49
	return false
50
}
51

  
52
def aborted = false
53

  
54
def scriptName = this.class.getSimpleName()
55

  
56
columnList = columnList.split(",") as List
57

  
58
println "columnList = "+columnList
59

  
60
multipleValues = multipleValues.split(",") as List
61

  
62
// create output file
63
out = new FileOutputStream(outputFile)
64
HSSFWorkbook wb = new HSSFWorkbook()
65
finalSheet = wb.createSheet()
66

  
67
// create header line
68
nFinalRows = 1
69
r = finalSheet.createRow(0)
70
columnList.eachWithIndex { columnName, i ->
71
	c = r.createCell(i)
72
	c.setCellValue(normalizeIdentifiers?stringToIdent(columnName):columnName)
73
}
74

  
75
def f = []
76

  
77
inputDirectory.eachFileMatch(~/.*\.xlsx/) { f << it }
78

  
79
if (f.size() == 0) {
80
	println "** $scriptName: no .xlsx file found. Aborting."
81
	return false
82
}
83

  
84
debug = false
85
//ConsoleProgressBar cpb = new ConsoleProgressBar(f.size())
86

  
87
try {
88

  
89
	// for each .xlsx input file (lexicographic order)
90
	f.sort { it.name }.each { inputFile ->
91

  
92
		if (aborted) return false
93

  
94
		if (debug) println "Processing "+inputFile+"."
95
		//cpb.tick()
96
		rownum = 0
97

  
98
		// open input sheet
99
		wb2 = WorkbookFactory.create(inputFile)
100
		ws = null
101
		if (sheetName.length() == 0) {
102
			ws = wb2.getSheetAt(0)
103
		} else {
104
			ws = wb2.getSheet(sheetName)
105
			if (ws == null) {
106
				println "** $scriptName: no '"+sheetName+" found. Aborting."
107
				aborted = true
108
				return false
109
			}
110
		}
111

  
112
		if (ws == null) {
113
			println "** $scriptName: no sheet found. Aborting."
114
			aborted = true
115
			return false
116
		}
117

  
118
		nRows = ws.getPhysicalNumberOfRows()
119
		if (debug) println nRows+" rows."
120

  
121
		// get columns positions
122
		firstRow = ws.getRow(0)
123
		nCols = firstRow.getPhysicalNumberOfCells()
124
		def colNames = []
125
		def cellIndexes = []
126
		def multipleValuesCols = []
127
		0.upto(nCols-1, { iCol ->
128
			value = firstRow.getCell(iCol).getStringCellValue()
129
			if (columnList.contains(value)) {
130
				colNames << value
131
				cellIndexes << iCol
132
			}
133
			if (multipleValues.contains(value)) {
134
				multipleValuesCols << iCol
135
			}
136
		})
137

  
138
		if (cellIndexes.size() != columnList.size()) {
139
			columnList.removeAll(colNames)
140
			println "** $scriptName: some columns missing in file $inputFile: "+columnList.join(", ")+". Aborting."
141

  
142
			aborted = true
143
			return false
144
		}
145

  
146
		// sort columns indexes by columnList parameter order
147
		cellIndexes.sort { columnList.indexOf(colNames[cellIndexes.indexOf(it)]) }
148

  
149
		// copy column values
150
		1.upto(nRows-1, { iRow ->
151
			row = ws.getRow(iRow)
152
			r = finalSheet.createRow(nFinalRows)
153
			
154
			nCellCreated = 0
155
			cellIndexes.each { iCol ->
156
				value = row.getCell(iCol).getStringCellValue()
157
				c = r.createCell(nCellCreated)
158
				if (iCol in multipleValuesCols && value.size() > 0) {
159
					(lstr = value.split(";")*.trim() as List).removeAll { it.isEmpty() }
160
					c.setCellValue("|"+lstr.join("|")+"|")
161
				} else {
162
					c.setCellValue(value)
163
				}
164
				nCellCreated++
165
			}
166
			
167
			nFinalRows++
168
		})
169
	}
170
} catch(Exception e) {
171
	aborted = true
172
	return false
173
}
174
//cpb.done()
175

  
176
/* write sheet */
177

  
178
wb.write(out)
179
out.close()
180

  
181
if (aborted) return false
182

  
183
println nFinalRows+" rows written."
184

  
185
return true
186

  
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/stats/CAStyleMacro.groovy (revision 3555)
1
// STANDARD DECLARATIONS
2
// @author mdecorde sjacquot sheiden
3
package org.txm.macro
4

  
5
import org.kohsuke.args4j.*
6
import groovy.transform.Field
7
import org.txm.rcpapplication.swt.widget.parameters.*
8
import org.txm.searchengine.cqp.clientExceptions.*
9
import org.txm.searchengine.cqp.corpus.*
10
import org.txm.searchengine.cqp.corpus.query.*
11
import org.apache.commons.lang.time.StopWatch
12
import java.util.Arrays
13
import org.jfree.chart.renderer.xy.*
14
import org.jfree.chart.renderer.*
15
import org.jfree.chart.plot.*
16
import org.jfree.data.xy.*
17
import org.jfree.chart.axis.*
18
import java.awt.*;
19
import java.awt.geom.*;
20
import org.jfree.chart.labels.*
21

  
22
import org.txm.ca.core.functions.CA
23
import org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.renderers.*
24
import org.txm.ca.rcp.editors.*
25
import org.txm.libs.office.ReadODS
26
import org.txm.ca.core.chartsengine.jfreechart.datasets.*
27
import org.jfree.chart.renderer.AbstractRenderer
28
import java.awt.geom.Ellipse2D
29
import org.jfree.chart.util.ShapeUtils
30

  
31

  
32
println "editor: "+editor
33

  
34
if (!(editor instanceof CAEditor)) {
35
	println "editor is not a CA editor: $editor, Run the macro with F12 when the editor is selected :-)"
36
	return
37
}
38

  
39
@Field @Option(name="patternsODSFile", usage="The starting word", widget="FileOpen", required=true, def='patterns.ods')
40
def patternsODSFile
41
@Field @Option(name="debug", usage="Show internal variable content", widget="StringArray", metaVar="OFF	ON	ALL	REALLY ALL", required=true, def="OFF")
42
debug
43

  
44
// Open the parameters input dialog box
45
if (!ParametersDialog.open(this)) return;
46
if (debug == "OFF") debug = 0; else if (debug == "ON") debug = 1; else if (debug == "ALL") debug = 2 else if (debug == "REALLY ALL") debug = 3
47

  
48
if (!patternsODSFile.exists()) {
49
	println "Pattern file not found: $patternsODSFile"
50
	return false;
51
}
52
if (!patternsODSFile.isFile() || !patternsODSFile.getName().toLowerCase().endsWith(".ods")) {
53
	println "Wrong pattern file: $patternsODSFile"
54
	return false;
55
}
56

  
57
def data = ReadODS.toTable(patternsODSFile, "rows")
58
def keys = data[0]
59
def row_styles = [:] // reformat data
60
	for (int i = 1 ; i < data.size() ; i++) {
61
		def h = data[i]
62
		def style = [:] // create style entry
63
		String s = h[0];
64
		row_styles[/$s/] = style // with a regexp pattern as key
65
				
66
		// fill the style
67
		for (int j = 1 ; j < h.size() ; j++) {
68
			style[keys[j]] = h[j]
69
		}
70
	}
71
if (debug > 0) {
72
	println "ROW STYLES=$row_styles"
73
}
74

  
75
data = ReadODS.toTable(patternsODSFile, "cols")
76
keys = data[0]
77
def col_styles = [:] // reformat data
78

  
79
for (int i = 1 ; i < data.size() ; i++) {
80
	def h = data[i]
81
	def style = [:] // create style entry
82
	String s = h[0];
83
	col_styles[/$s/] = style // with a regexp pattern as key
84
					
85
	// fill the style
86
	for (int j = 1 ; j < h.size() ; j++) {
87
		style[keys[j]] = h[j]
88
	}
89
}
90
if (debug > 0) {
91
	println "COL STYLES=$col_styles"
92
}
93

  
94
ica = editor.getCA()
95
ca = ica.getCA()
96

  
97
// http://txm.sourceforge.net/javadoc/TXM/TBX/org/txm/stat/engine/r/function/CA.html
98

  
99
// SOME DATA
100
rows = ica.getRowNames()
101
rowsinfo = ica.getRowInfos()
102
rowscos2 = ca.getRowCos2()
103
cols = ica.getColNames()
104
colssinfo = ica.getColInfos()
105
colscos2 = ca.getColCos2()
106
D1 = ica.getFirstDimension() -1;
107
D2 = ica.getSecondDimension() -1;
108

  
109
// create some AWT shapes for replacement
110
shapes = new HashMap<String, Shape>();
111
// dimensions scaling factor (the same used in default theme for the replaced shapes have same dimension than non-replaced)
112
float itemShapesScalingFactor = 1.2f
113
shapes["diamond"] = ShapeUtils.createDiamond((float)(itemShapesScalingFactor * 3.4f));
114
shapes["square"] = AbstractRenderer.DEFAULT_SHAPE;
115

  
116
float circleSize = 6.4f * itemShapesScalingFactor;
117
shapes["disk"] = new Ellipse2D.Float((float)(-circleSize / 2), (float)(-circleSize / 2), circleSize, circleSize);
118

  
119
shapes["triangle"] = ShapeUtils.createUpTriangle((float)(itemShapesScalingFactor * 3.2f));
120

  
121
//shapes["star"] = AbstractRenderer.DEFAULT_SHAPE;
122
//shapes["circle"] = AbstractRenderer.DEFAULT_SHAPE;
123

  
124

  
125
println "SHAPES=$shapes"
126

  
127

  
128
// styles per col index in dataset
129
// set col label
130
colLabelStyle = new HashMap<Integer, String>();
131
// set col visibility
132
colHiddenStyle = new HashSet<Integer>(); // true false
133
// set col font size
134
colFontSizeStyle = new HashMap<Integer, Float>();
135
// set col font color
136
colFontColorStyle = new HashMap<Integer, Color>();
137
// set col font family
138
colFontFamilyStyle = new HashMap<Integer, String>();
139
// set col points size
140
colPointSizeStyle = new HashMap<Integer, Double>();
141
// set col points RGBA color
142
colPointColorStyle = new HashMap<Integer, Color>();
143
// set col points shape (circle, square, triangle, ... + color ? + size ?) -> expert
144
colPointShapeStyle = new HashMap<Integer, Shape>(); // circle, square, triangle, etc.
145
// set col font style (1 = bold, 2 = italic, 3 = bold + italic)
146
colFontStyleStyle = new HashMap<Integer, Integer>();
147

  
148

  
149
// set row label
150
rowLabelStyle = new HashMap<Integer, String>();
151
// set row visibility
152
rowHiddenStyle = new HashSet<Integer>(); // true false
153
// set row font size
154
rowFontSizeStyle = new HashMap<Integer, Float>();
155
// set row font size
156
rowFontColorStyle = new HashMap<Integer, Color>();
157
// set row font size
158
rowFontFamilyStyle = new HashMap<Integer, String>();
159
// set row points size
160
rowPointSizeStyle = new HashMap<Integer, Double>();
161
// set row points RGBA color
162
rowPointColorStyle = new HashMap<Integer, Color>();
163
// set row points shape (circle, square, triangle, ... + color ? + size ?) -> expert
164
rowPointShapeStyle = new HashMap<Integer, Shape>(); // circle, square, triangle, etc.
165
// set row font style (1 = bold, 2 = italic, 3 = bold + italic)
166
rowFontStyleStyle = new HashMap<Integer, Integer>();
167

  
168
// prepare col style data for the dataset
169
for (int i = 0 ; i < cols.length ; i++) {
170
	for (def p : col_styles.keySet()) {
171
		if (cols[i] ==~ p) {
172
			def style = col_styles[p]
173
			if (style["label-replacement"] != null && style["label-replacement"].length() > 0) {
174
				colLabelStyle[i] = style["label-replacement"]
175
			}
176
			if (style["hidden"] != null && style["hidden"].toUpperCase() == "T") {
177
				colHiddenStyle << i
178
			}
179
			if (style["shape-size"] != null && style["shape-size"].length() > 0) {
180
				colPointSizeStyle[i] = Double.parseDouble(style["shape-size"])
181
			}
182
			if (style["shape-color"] != null && style["shape-color"].length() > 0 ) {
183
				colPointColorStyle[i] = rgbaStringToColor(style["shape-color"])
184
			}
185
			if (style["shape-replacement"] != null && shapes.containsKey(style["shape-replacement"])) {
186
				colPointShapeStyle[i] = shapes[style["shape-replacement"]]
187
			}
188
			if (style["label-size"] != null && style["label-size"].length() > 0) {
189
				colFontSizeStyle[i] = Float.parseFloat(style["label-size"])
190
			}
191
			if (style["label-color"] != null && style["label-color"].length() > 0) {
192
				colFontColorStyle[i] = rgbaStringToColor(style["label-color"])
193
			}
194
			if (style["label-font-family"] != null && style["label-font-family"].length() > 0) {
195
				colFontFamilyStyle[i] = style["label-font-family"]
196
			}
197
			if (style["label-style"] != null && style["label-style"].length() > 0) {
198
				colFontStyleStyle[i] = Integer.parseInt(style["label-style"])
199
			}
200
			
201
		}
202
	}
203
}
204
if (debug > 0) {
205
	println "COL COL=$colPointColorStyle"
206
	println "COL SHP=$colPointShapeStyle"
207
	println "COL LAB=$colLabelStyle"
208
	println "COL FONT-SIZ=$colFontSizeStyle"
209
	println "COL SIZ=$colPointSizeStyle"
210
	println "COL VIZ=$colHiddenStyle"
211
	println "COL STYLE=$colFontStyleStyle"
212
}
213

  
214
// prepare row style data for the dataset
215
for (int i = 0 ; i < rows.length ; i++) {
216
	for (def p : row_styles.keySet()) {
217
		if (rows[i] ==~ p) {
218
			def style = row_styles[p]
219
			if (style["hidden"] != null && style["hidden"].toUpperCase() == "T") {
220
				rowHiddenStyle << i
221
			}
222
			if (style["label-replacement"] != null && style["label-replacement"].length() > 0) {
223
				rowLabelStyle[i] = style["label-replacement"]
224
			}
225
			if (style["shape-size"] != null && style["shape-size"].length() > 0) {
226
				rowPointSizeStyle[i] = Double.parseDouble(style["shape-size"])
227
			}
228
			if (style["shape-color"] != null && style["shape-color"].length() > 0 ) {
229
				rowPointColorStyle[i] = rgbaStringToColor(style["shape-color"])
230
			}
231
			if (style["shape-replacement"] != null && shapes.containsKey(style["shape-replacement"])) {
232
				rowPointShapeStyle[i] = shapes[style["shape-replacement"]]
233
			}
234
			if (style["label-size"] != null && style["label-size"].length() > 0) {
235
				rowFontSizeStyle[i] = Float.parseFloat(style["label-size"])
236
			}
237
			if (style["label-color"] != null && style["label-color"].length() > 0) {
238
				rowFontColorStyle[i] = rgbaStringToColor(style["label-color"])
239
			}
240
			if (style["label-font-family"] != null && style["label-font-family"].length() > 0) {
241
				rowFontFamilyStyle[i] = style["label-font-family"]
242
			}
243
			if (style["label-style"] != null && style["label-style"].length() > 0) {
244
				rowFontStyleStyle[i] = Integer.parseInt(style["label-style"])
245
			}
246
		}
247
	}
248
}
249
if (debug > 0) {
250
	println "ROW COL=$rowPointColorStyle"
251
	println "ROW SHP=$rowPointShapeStyle"
252
	println "ROW LAB=$rowLabelStyle"
253
	println "ROW FONT-SIZ=$rowFontSizeStyle"
254
	println "ROW SIZ=$rowPointSizeStyle"
255
	println "ROW VIZ=$rowHiddenStyle"
256
	println "ROW STYLE=$rowFontStyleStyle"
257
}
258

  
259

  
260

  
261
// Redefine the chart renderer and update the chart
262
def chartEditor = editor.getEditors()[0]
263
def chartComposite = chartEditor.getComposite()
264

  
265
ddebug = debug
266
monitor.syncExec( new Runnable() {
267

  
268
	public void run() {
269
		println chartComposite
270
		def chart = chartEditor.getChart()
271
		
272
		/*
273
		println "chart: "+chart
274
		println "Plot: "+chart.getPlot()
275
		println "Dataset: "+chart.getPlot().getDataset()
276
		println "Renderer 1: "+chart.getPlot().getRenderer()
277
		 */
278
		
279
		def renderer = new CAItemSelectionRenderer(ica, chart) {
280
			Area EMPTYAREA = new Area()
281
					
282
					@Override
283
					public void initItemLabelGenerator() {
284
					XYItemLabelGenerator generator = new XYItemLabelGenerator() {
285
					
286
					@Override
287
					public String generateLabel(XYDataset dataset, int series, int item) {
288
						if (series == 0 && rowHiddenStyle.contains(item)) {
289
							if (ddebug > 1) println "HIDDING ROW LABEL '$item' '${rows[item]}'"
290
							return ""
291
						} else if (series == 1 && colHiddenStyle.contains(item)) {
292
							if (ddebug > 1) println "HIDDING COL LABEL '$item' '${cols[item]}'"
293
							return ""
294
						} else if (series == 0 && rowLabelStyle.containsKey(item)) {
295
							if (ddebug > 1) println "RENAME ROW LABEL '$item' '${rows[item]}' -> '${rowLabelStyle[item]}'"
296
							return rowLabelStyle[item]
297
						} else if (series == 1 && colLabelStyle.containsKey(item)) {
298
							if (ddebug > 1) println "RENAME COL LABEL '$item' '${cols[item]}' -> '${colLabelStyle[item]}'"
299
							return colLabelStyle[item]
300
						} else {
301
							CAXYDataset caDataset = (CAXYDataset) dataset;
302
							return caDataset.getLabel(series, item);
303
						}
304
					}
305
				};
306
				
307
				// don't use setBaseItemLabelGenerator BUT setDefaultItemLabelGenerator
308
				this.setDefaultItemLabelGenerator(generator);
309
				this.setDefaultItemLabelsVisible(true);
310
			}
311
			
312
			
313
			
314
			@Override
315
			public Font getItemLabelFont(int series, int item) {
316
				Font d = super.getItemLabelFont(series, item);
317
				Integer style = d.getStyle();
318
				Integer size = d.getSize();
319
				String family = d.getFontName();
320
				
321
				// size
322
				if (series == 0 && rowFontSizeStyle.containsKey(item)) {
323
					if (ddebug > 1) println "FIX ROW FONT-SIZE $item ${rows[item]} -> ${rowFontSizeStyle[item]}"
324
					size *= rowFontSizeStyle[item];
325
				} else if (series == 1 && colFontSizeStyle.containsKey(item)) {
326
					if (ddebug > 1) println "FIX COL FONT-SIZE $item ${cols[item]} -> ${colFontSizeStyle[item]}"
327
					size *= colFontSizeStyle[item];
328
				}
329
				
330
				// family
331
				if (series == 0 && rowFontFamilyStyle.containsKey(item)) {
332
					if (ddebug > 1) println "FIX ROW FONT-Family $item ${rows[item]} -> ${rowFontFamilyStyle[item]}"
333
					family = rowFontFamilyStyle[item];
334
				} else if (series == 1 && colFontFamilyStyle.containsKey(item)) {
335
					if (ddebug > 1) println "FIX COL FONT-Family $item ${cols[item]} -> ${colFontFamilyStyle[item]}"
336
					family = colFontFamilyStyle[item];
337
				}
338
				
339
				// style
340
				if (series == 0 && rowFontStyleStyle.containsKey(item)) {
341
					if (ddebug > 1) println "FIX ROW FONT-Style $item ${rows[item]} -> ${rowFontStyleStyle[item]}"
342
					style = rowFontStyleStyle[item];
343
				} else if (series == 1 && colFontFamilyStyle.containsKey(item)) {
344
					if (ddebug > 1) println "FIX COL FONT-Style $item ${cols[item]} -> ${colFontStyleStyle[item]}"
345
					style = colFontStyleStyle[item];
346
				}
347
				
348
				
349
				return new Font(family, style, size);
350
			}
351
			
352
			
353
			@Override
354
			public Shape getItemShape(int series, int item) {
355
				// Rows (series == 0), Cols (series == 1)
356
				if (series == 0 && rowHiddenStyle.contains(item)) {
357
					return EMPTYAREA;
358
				} else if (series == 1 && colHiddenStyle.contains(item)) {
359
					return EMPTYAREA;
360
				} else {
361
					
362
					Shape shape =  super.getItemShape(series, item);
363
					
364
					// not-visible shapes mode
365
					if(!((CA) this.multipleItemsSelector.getResult()).isShowPointShapes())        {
366
						return shape;
367
					}
368
					
369
					// shape replacement
370
					if (series == 0 && rowPointShapeStyle.containsKey(item)) {
371
						if (ddebug > 1) println "FIX ROW SHAPE $item ${rows[item]} -> ${rowPointShapeStyle[item]}"
372
						shape = rowPointShapeStyle.get(item);
373
					} else if (series == 1 && colPointShapeStyle.containsKey(item)) {
374
						if (ddebug > 1) println "FIX COL SHAPE $item ${cols[item]} -> ${colPointShapeStyle[item]}"
375
						shape = colPointShapeStyle.get(item);
376
					}
377
					
378
					
379
					// shape scaling
380
					AffineTransform t = new AffineTransform();
381
					if (series == 0 && rowPointSizeStyle.containsKey(item)) {
382
						if (ddebug > 1) println "FIX ROW POINT SIZE $item ${rows[item]} -> ${rowPointSizeStyle[item]}"
383
						t.setToScale(rowPointSizeStyle.get(item), rowPointSizeStyle.get(item));
384
						shape = t.createTransformedShape(shape);
385
					} else if (series == 1 && colPointSizeStyle.containsKey(item)) {
386
						if (ddebug > 1) println "FIX COL POINT SIZE $item ${cols[item]} -> ${colPointSizeStyle[item]}"
387
						t.setToScale(colPointSizeStyle.get(item), colPointSizeStyle.get(item));
388
						shape = t.createTransformedShape(shape);
389
					}
390
					
391
					return shape;
392
				}
393
			}
394
			
395
			
396
			@Override
397
			public Paint getItemPaint(int series, int item) {
398
				
399
				// visible shapes mode
400
				if (!((CA) this.multipleItemsSelector.getResult()).isShowPointShapes()) {
401
					return super.getItemPaint(series, item);
402
				}
403
				
404
				if (series == 0 && rowPointColorStyle.containsKey(item)) {
405
					if (ddebug > 1) println "FIX ROW POINT COLOR $item ${rows[item]} -> ${rowPointColorStyle[item]}"
406
					return rowPointColorStyle.get(item);
407
				} else if (series == 1 && colPointColorStyle.containsKey(item)) {
408
					if (ddebug > 1) println "FIX COL POINT COLOR $item ${cols[item]} -> ${colPointColorStyle[item]}"
409
					return colPointColorStyle.get(item);
410
				}
411
				else {
412
					return super.getItemPaint(series, item);
413
				}
414
			}
415
			
416
			
417
			@Override
418
			public Paint getItemLabelPaint(int series, int item) {
419
				if (series == 0 && rowFontColorStyle.containsKey(item)) {
420
					if (ddebug > 1) println "FIX ROW LABEL COLOR $item ${rows[item]} -> ${rowFontColorStyle[item]}"
421
					return rowFontColorStyle.get(item);
422
				} else if (series == 1 && colFontColorStyle.containsKey(item)) {
423
					if (ddebug > 1) println "FIX COL LABEL COLOR $item ${cols[item]} -> ${colFontColorStyle[item]}"
424
					return colFontColorStyle.get(item);
425
				} else {
426
					return super.getItemLabelPaint(series, item);
427
				}
428
			}
429
			
430
		};
431
		
432
		
433
		def cp = editor.editors[0].getChart();
434
		renderer.chart = cp // SJ: seems useless
435
		renderer.setSeriesVisible(0, ica.isShowVariables()); // Rows  // SJ: seems useless
436
		renderer.setSeriesVisible(1, ica.isShowIndividuals()); // Columns  // SJ: seems useless
437
		chart.getXYPlot().setRenderer(renderer)
438
		
439
		ica.getChartCreator().updateChart(chartEditor.getResult())
440
		
441
	}
442
});
443

  
444

  
445

  
446

  
447
// creates a Color object from the specified RGB or RGBA string representation separated by spaces ("R G B" or "R G B A") from 0 to 255 for each channel
448
def rgbaStringToColor(String color) {
449
	String[] rgbColor = color.split(" ");
450
	String alpha = "255";
451
	if(rgbColor.length > 2) {
452
		if(rgbColor.length > 3) {
453
			alpha = rgbColor[3];
454
		}
455
		return new Color(Integer.parseInt(rgbColor[0]), Integer.parseInt(rgbColor[1]), Integer.parseInt(rgbColor[2]), Integer.parseInt(alpha))
456
	}
457
	else {
458
		println "Error in color format for RGB or RGBA string: $color"
459
	}
460
}
461

  
462

  
463

  
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/stats/CAFilter.groovy (revision 3555)
1
// STANDARD DECLARATIONS
2
package org.txm.macro
3

  
4
import org.kohsuke.args4j.*
5
import groovy.transform.Field
6
import org.txm.rcpapplication.swt.widget.parameters.*
7
import org.txm.searchengine.cqp.clientExceptions.*
8
import org.txm.searchengine.cqp.corpus.*
9
import org.txm.searchengine.cqp.corpus.query.*
10
import org.apache.commons.lang.time.StopWatch
11
import java.util.Arrays
12
import org.jfree.chart.renderer.xy.*
13
import org.jfree.chart.renderer.*
14
import org.jfree.chart.plot.*
15
import org.jfree.data.xy.*
16
import org.jfree.chart.axis.*
17
import java.awt.*;
18
import java.awt.geom.*;
19
import org.jfree.chart.labels.*
20

  
21
import org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.renderers.*
22
import org.txm.ca.rcp.editors.*
23
import org.txm.libs.office.ReadODS
24
import org.txm.ca.core.chartsengine.jfreechart.datasets.*
25
import org.jfree.chart.renderer.AbstractRenderer
26

  
27
import org.apache.commons.math3.stat.descriptive.*
28

  
29
println "editor: "+editor
30

  
31
if (!(editor instanceof CAEditor)) {
32
	println "editor is not a CA editor: $editor, Run the macro with F12 when the editor is selected :-)"
33
	return
34
}
35

  
36
def chartEditor = editor.getEditors()[0]
37
def chartComposite = chartEditor.getComposite()
38

  
39
// BEGINNING OF PARAMETERS
40

  
41
// Declare each parameter here
42
// (available widget types: Query, File, Folder, String, Text, Boolean, Integer, Float and Date)
43

  
44
//@Field @Option(name="query", usage="an example query", widget="Query", required=true, def='[pos="V.*"]')
45
//def query
46

  
47
//@Field @Option(name="file", usage="an example file", widget="File", required=true, def="C:/Temp/foo.txt")
48
//def file
49

  
50
//@Field @Option(name="folder", usage="an example folder", widget="Folder", required=false, def="C:/Temp")
51
//def folder
52

  
53
//@Field @Option(name="date", usage="an example date", widget="Date", required=false, def="1984-09-01")
54
//def date
55

  
56
//@Field @Option(name="integer", usage="an example integer", widget="Integer", required=false, def="42")
57
//def integer
58

  
59
@Field @Option(name="QMin", usage="min Q", widget="Float", required=true, def="0.01")
60
def QMin
61

  
62
@Field @Option(name="CTRXMin", usage="min CTR X", widget="Float", required=true, def="0.001")
63
def CTRXMin
64

  
65
@Field @Option(name="CTRYMin", usage="min CTR Y", widget="Float", required=true, def="0.001")
66
def CTRYMin
67

  
68
@Field @Option(name="stackX", usage="stack X", widget="Float", required=true, def="0.0")
69
def stackX
70

  
71
@Field @Option(name="stackY", usage="stack Y", widget="Float", required=true, def="0.0")
72
def stackY
73

  
74
//@Field @Option(name="string", usage="an example string", widget="String", required=false, def="hello world!")
75
//def string
76

  
77
@Field @Option(name="regexFilter", usage="row property form regex", widget="Text", required=false, def="")
78
def regexFilter
79

  
80
@Field @Option(name="debug", usage="debug (verbose) mode", widget="Boolean", required=true, def="true")
81
def debug
82

  
83
// La fenêtre de résultats
84
CAresultWindow = editor
85

  
86
// Le tableau de données d'aide à l'interprétation
87
// Les données de l'AFC sont manipulables par les méthodes documentées ici http://txm.sourceforge.net/javadoc/TXM/TBX/org/txm/stat/engine/r/function/CA.html
88

  
89
ica = CAresultWindow.getCA()
90
ca = ica.getCA()
91

  
92
rowNames = ica.getRowNames()
93
rowCos2 = ca.getRowCos2()
94
rowContrib = ca.getRowContrib()
95

  
96
colNames = ica.getColNames()
97
colCos2 = ca.getColCos2()
98
colContrib = ca.getColContrib()
99

  
100
F1 = ica.getFirstDimension()-1
101
F2 = ica.getSecondDimension()-1
102

  
103
println sprintf("F1 = %d, F2 = %d, %d initial rows, %d initial cols", F1+1, F2+1, rowNames.length, colNames.length)
104

  
105
def stats = { vector, factor ->
106
	s = new DescriptiveStatistics()
107
	(vector.length).times {
108
		s.addValue(vector[it][factor]);
109
	}
110

  
111
	println "min       quartile  median    third quartile  max"
112
	println sprintf("%8f  %8f  %8f  %8f        %8f", s.getMin(), s.getPercentile(25), s.getPercentile(50), s.getPercentile(75), s.getMax())
113
}
114

  
115
// rows
116

  
117
println "ROWS -----"
118
println "CTR"+(F1+1)
119
stats(rowContrib, F1)
120

  
121
println "CTR"+(F2+1)
122
stats(rowContrib, F2)
123

  
124
println "Cos² "+(F1+1)
125
stats(rowCos2, F1)
126

  
127
println "Cos² "+(F2+1)
128
stats(rowCos2, F2)
129

  
130
// cols
131

  
132
println "COLS -----"
133
println "CTR"+(F1+1)
134
stats(colContrib, F1)
135

  
136
println "CTR"+(F2+1)
137
stats(colContrib, F2)
138

  
139
println "Cos² "+(F1+1)
140
stats(colCos2, F1)
141

  
142
println "Cos² "+(F2+1)
143
stats(colCos2, F2)
144

  
145

  
146
def stats2 = { vector, factor1, factor2 ->
147
	s = new DescriptiveStatistics()
148
	(vector.length).times {
149
		s.addValue(vector[it][factor1]+vector[it][factor2]);
150
	}
151

  
152
	println "min       quartile  median    third quartile  max"
153
	println sprintf("%8f  %8f  %8f  %8f        %8f", s.getMin(), s.getPercentile(25), s.getPercentile(50), s.getPercentile(75), s.getMax())
154
}
155

  
156
println "Q"+(F1+1)+(F2+1)
157
stats2(rowCos2, F1, F2)
158

  
159
println "Q"+(F1+1)+(F2+1)
160
stats2(colCos2, F1, F2)
161

  
162
// Open the parameters input dialog box
163
if (!ParametersDialog.open(this)) return
164

  
165
// END OF PARAMETERS
166

  
167

  
168
filteredRows = []
169

  
170
println ""
171

  
172
if (debug) println "\nROWS -----"
173

  
174
if (regexFilter.length() > 0) {
175
	nmatched = 0
176
	rowNames.each { it ->
177
		if (it ==~ regexFilter) {
178
			if (debug && !filteredRows.contains(it)) {
179
				if (nmatched > 0) print ", "
180
				print it
181
			}
182
			filteredRows << it
183
			nmatched++
184
		}
185
	}
186

  
187
	if (debug && nmatched > 0) println ""
188

  
189
	if (debug) {
190
		println sprintf("\n%d rows filtered by regex", nmatched)
191
	}
192

  
193
}
194

  
195
nQCTR = 0
196
rowNames.eachWithIndex { it, i ->
197
	def cos2 = rowCos2[i]
198
	if ((rowContrib[i][F1] < CTRXMin) && (rowContrib[i][F2] < CTRYMin) && (cos2[F1] + cos2[F2] < QMin)) {
199
		if (debug && !filteredRows.contains(rowNames[i])) {
200
			if (nQCTR > 0) print ", "
201
			print rowNames[i]
202
		}
203
		filteredRows << rowNames[i]
204
		nQCTR++
205
	}
206
}
207

  
208
if (debug) {
209
	println sprintf("\n%d rows filtered by CTR or Q"+(F1+1)+(F2+1), nQCTR)
210
}
211

  
212
// cols
213

  
214
filteredCols = []
215

  
216
println ""
217

  
218
if (debug) println "\nCOLS -----"
219

  
220
if (regexFilter.length() > 0) {
221
	nmatched = 0
222
	colNames.each { it ->
223
		if (it ==~ regexFilter) {
224
			if (debug && !filteredCols.contains(it)) {
225
				if (nmatched > 0) print ", "
226
				print it
227
			}
228
			filteredCols << it
229
			nmatched++
230
		}
231
	}
232

  
233
	if (debug && nmatched > 0) println ""
234

  
235
	if (debug) {
236
		println sprintf("\n%d cols filtered by regex", nmatched)
237
	}
238

  
239
}
240

  
241
nQCTR = 0
242
colNames.eachWithIndex { it, i ->
243
	def cos2 = colCos2[i]
244
	if (!((colContrib[i][F1] > CTRXMin) || (colContrib[i][F2] > CTRYMin) || (cos2[F1] + cos2[F2] > QMin))) {
245
		if (debug && !filteredCols.contains(colNames[i])) {
246
			if (nQCTR > 0) print ", "
247
			print colNames[i]
248
		}
249
		filteredCols << colNames[i]
250
		nQCTR++
251
	}
252
}
253

  
254
if (debug) {
255
	println sprintf("\n%d cols filtered by CTR or Q"+(F1+1)+(F2+1), nQCTR)
256
}
257

  
258
double stackXv = stackX
259
double stackYv = stackY
260

  
261

  
262
// Visualisation graphique
263

  
264
chartCAresultWindow = CAresultWindow.getEditors()[0]
265
chartComposite = chartCAresultWindow.getComposite()
266

  
267
monitor.syncExec( new Runnable() {
268
	public void run() {
269

  
270
				println chartComposite
271
				def chart = chartEditor.getChart();
272

  
273
				dataset2 = new CAXYDataset(ica)
274
				
275
				labels = dataset2.rowLabels
276
				coords = dataset2.rowCoordinates
277
				(labels.length).times {
278
					if (filteredRows.contains(labels[it])) {
279
						println "Moving "+labels[it]+" row to origin."
280
						labels[it] = ""
281
						coords[it][F1] = stackXv
282
						coords[it][F2] = stackYv
283
					}
284
				}
285
				labels = dataset2.columnLabels
286
				coords = dataset2.columnCoordinates
287
				(labels.length).times {
288
					if (filteredCols.contains(labels[it])) {
289
						println "Moving "+labels[it]+" col to origin."
290
						labels[it] = ""
291
						coords[it][F1] = stackXv
292
						coords[it][F2] = stackYv
293
					}
294
				}
295

  
296
				chart.getXYPlot().setDataset(dataset2)
297

  
298
				ica.getChartCreator().getChartsEngine().getJFCTheme().apply(chart); // need to be call AFTER setRenderer() cause this method changes some renderering parameters
299
				chartComposite.loadChart()
300
			}
301
})
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/stats/InvertCAXAxisMacro.groovy (revision 3555)
1
// @author Sebastien Jacquot
2
// STANDARD DECLARATIONS
3
package org.txm.macro
4

  
5

  
6
import org.kohsuke.args4j.*
7
import groovy.transform.Field
8
import org.txm.rcpapplication.swt.widget.parameters.*
9
import org.txm.searchengine.cqp.clientExceptions.*
10
import org.txm.searchengine.cqp.corpus.*
11
import org.txm.searchengine.cqp.corpus.query.*
12
import org.apache.commons.lang.time.StopWatch
13
import java.util.Arrays
14
import org.jfree.chart.renderer.xy.*
15
import org.jfree.chart.renderer.*
16
import org.jfree.chart.plot.*
17
import org.jfree.data.xy.*
18
import org.jfree.chart.axis.*
19
import java.awt.*;
20
import java.awt.geom.*;
21
import org.jfree.chart.labels.*
22

  
23
import org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.renderers.*
24
import org.txm.ca.rcp.editors.*
25
import org.txm.libs.office.ReadODS
26
import org.txm.ca.core.chartsengine.jfreechart.datasets.*
27
import org.jfree.chart.renderer.AbstractRenderer
28

  
29
println "editor: "+editor
30

  
31
if (!(editor instanceof CAEditor)) {
32
	println "editor is not a CA editor: $editor, Run the macro with F12 when the editor is selected :-)"
33
	return
34
}
35

  
36
ica = editor.getCA();
37
chart = ica.getChart();
38
plot = chart.getXYPlot();
39
dataset = plot.getDataset(); 
40

  
41
// overrides some dataset methods to return inverted X coordinates for columns and rows
42
plot.setDataset(new CAXYDataset(ica) {
43

  
44
        public Number getX(int series, int item) {
45
                if(item == -1)        {
46
                        System.out.println("CAXYDataset.getX()");
47
                }
48
                // Rows
49
                if(series == 0) {
50
                        return -this.rowCoordinates[item][this.axis1];
51
                }
52
                // Cols
53
                else {
54
                        return -this.columnCoordinates[item][this.axis1];
55
                }
56
        }
57
        
58
        
59
         
60
        /**
61
         * Gets the minimum value in the specified series according to the specified axis.
62
         * @param series
63
         * @param axis
64
         * @return
65
         */
66
        public double getMinValue(int series, int axis)        {
67
                double minValue = 0;
68
                double tmpMinValue;
69
                double[][] coordinates = this.rowCoordinates;
70
                if(series != 0)        {
71
                        coordinates = this.columnCoordinates;
72
                }
73
                
74
                for(int i = 0; i < coordinates.length; i++) {
75
                        tmpMinValue = coordinates[i][axis];
76
                        
77
						// invert X coordinate
78
                		if(axis == 0)        {
79
                			tmpMinValue = -tmpMinValue;
80
                		}
81
                        
82
                        if(tmpMinValue < minValue)        {
83
                                minValue = tmpMinValue;
84
                        }
85
                }
86
                
87
                return minValue;
88
        }
89
        
90
        /**
91
         * Gets the maximum value in the specified series according to the specified axis.
92
         * @param series
93
         * @param axis
94
         * @return
95
         */
96
        public double getMaxValue(int series, int axis)        {
97
                double maxValue = 0;
98
                double tmpMaxValue;
99
                double[][] coordinates = this.rowCoordinates;
100
                if(series != 0)        {
101
                        coordinates = this.columnCoordinates;
102
                }
103
                
104
                for(int i = 0; i < coordinates.length; i++) {
105
                        tmpMaxValue = coordinates[i][axis];
106
                        
107
						// invert X coordinate
108
                		if(axis == 0)        {
109
                			tmpMaxValue = -tmpMaxValue;
110
                		}
111
                        
112
                        if(tmpMaxValue > maxValue)        {
113
                                maxValue = tmpMaxValue;
114
                        }
115
                }
116
                
117
                return maxValue;
118
        }
119
}
120
);
121

  
122
// update the limits dotted borders
123
ica.getChartCreator().createCAFactorialMapChartLimitsBorder(chart);
124

  
125

  
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/stats/PlotEllipsesMacro.groovy (revision 3555)
1
// STANDARD DECLARATIONS
2
package org.txm.macro
3

  
4
import org.txm.ca.core.functions.CA
5
import org.txm.statsengine.r.core.RWorkspace
6
import groovy.transform.Field
7
// BEGINNING OF PARAMETERS
8

  
9
if (!(corpusViewSelection instanceof CA)) {
10
	println "Selection is not a CA. Please select a CA result in the Corpus view"
11
	return;
12
}
13

  
14
def ca = corpusViewSelection
15

  
16
@Field @Option(name="outputFile", usage="an example file", widget="FileSave", required=true, def="file.svg")
17
def outputFile
18

  
19
@Field @Option(name="draw", usage="'row' or 'col'", widget="String", required=true, def="row")
20
def draw
21
// Open the parameters input dialog box
22
if (!ParametersDialog.open(this)) return;
23

  
24
// END OF PARAMETERS
25

  
26
def s = ca.getRSymbol()
27
def RW = RWorkspace.getRWorkspaceInstance()
28

  
29
def script = """
30
plot($s);
31
ellipseCA($s, ellipse=c("$draw"));
32
"""
33

  
34
RW.plot(outputFile, script);
35

  
36
println "Done: "+outputFile.getAbsolutePath()
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/stats/.~lock.clearPattern.ods# (revision 3555)
1
,mdecorde,L107533,14.10.2022 11:02,file:///home/mdecorde/.config/libreoffice/4;
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/stats/.~lock.resultPattern.ods# (revision 3555)
1
,mdecorde,L107533,14.10.2022 11:05,file:///home/mdecorde/.config/libreoffice/4;
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/stats/PlotEllipsesMacro.groovy (revision 3555)
1
// STANDARD DECLARATIONS
2
package org.txm.macro.stats
3

  
4
import org.txm.ca.core.functions.CA
5
import org.txm.statsengine.r.core.RWorkspace
6
import groovy.transform.Field
7
// BEGINNING OF PARAMETERS
8

  
9
if (!(corpusViewSelection instanceof CA)) {
10
	println "Selection is not a CA. Please select a CA result in the Corpus view"
11
	return;
12
}
13

  
14
def ca = corpusViewSelection
15

  
16
@Field @Option(name="outputFile", usage="an example file", widget="FileSave", required=true, def="file.svg")
17
def outputFile
18

  
19
@Field @Option(name="draw", usage="'row' or 'col'", widget="String", required=true, def="row")
20
def draw
21
// Open the parameters input dialog box
22
if (!ParametersDialog.open(this)) return;
23

  
24
// END OF PARAMETERS
25

  
26
def s = ca.getRSymbol()
27
def RW = RWorkspace.getRWorkspaceInstance()
28

  
29
def script = """
30
plot($s);
31
ellipseCA($s, ellipse=c("$draw"));
32
"""
33

  
34
RW.plot(outputFile, script);
35

  
36
println "Done: "+outputFile.getAbsolutePath()
TXM/trunk/org.txm.groovy.core/src/groovy/org/txm/macro/stats/CAStyleMacro.groovy (revision 3555)
1
// STANDARD DECLARATIONS
2
// @author mdecorde sjacquot sheiden
3
package org.txm.macro.stats
4

  
5
import org.kohsuke.args4j.*
6
import groovy.transform.Field
7
import org.txm.rcpapplication.swt.widget.parameters.*
8
import org.txm.searchengine.cqp.clientExceptions.*
9
import org.txm.searchengine.cqp.corpus.*
10
import org.txm.searchengine.cqp.corpus.query.*
11
import org.apache.commons.lang.time.StopWatch
12
import java.util.Arrays
13
import org.jfree.chart.renderer.xy.*
14
import org.jfree.chart.renderer.*
15
import org.jfree.chart.plot.*
16
import org.jfree.data.xy.*
17
import org.jfree.chart.axis.*
18
import java.awt.*;
19
import java.awt.geom.*;
20
import org.jfree.chart.labels.*
21

  
22
import org.txm.ca.core.functions.CA
23
import org.txm.ca.core.chartsengine.jfreechart.themes.highcharts.renderers.*
24
import org.txm.ca.rcp.editors.*
25
import org.txm.libs.office.ReadODS
26
import org.txm.ca.core.chartsengine.jfreechart.datasets.*
27
import org.jfree.chart.renderer.AbstractRenderer
28
import java.awt.geom.Ellipse2D
29
import org.jfree.chart.util.ShapeUtils
30

  
31

  
32
println "editor: "+editor
33

  
34
if (!(editor instanceof CAEditor)) {
35
	println "editor is not a CA editor: $editor, Run the macro with F12 when the editor is selected :-)"
36
	return
37
}
38

  
39
@Field @Option(name="patternsODSFile", usage="The starting word", widget="FileOpen", required=true, def='patterns.ods')
40
def patternsODSFile
41
@Field @Option(name="debug", usage="Show internal variable content", widget="StringArray", metaVar="OFF	ON	ALL	REALLY ALL", required=true, def="OFF")
42
debug
43

  
44
// Open the parameters input dialog box
45
if (!ParametersDialog.open(this)) return;
46
if (debug == "OFF") debug = 0; else if (debug == "ON") debug = 1; else if (debug == "ALL") debug = 2 else if (debug == "REALLY ALL") debug = 3
47

  
48
if (!patternsODSFile.exists()) {
49
	println "Pattern file not found: $patternsODSFile"
50
	return false;
51
}
52
if (!patternsODSFile.isFile() || !patternsODSFile.getName().toLowerCase().endsWith(".ods")) {
53
	println "Wrong pattern file: $patternsODSFile"
54
	return false;
55
}
56

  
57
def data = ReadODS.toTable(patternsODSFile, "rows")  // read from the "rows" sheet
58
def keys = data[0]
59
def row_styles = [:] // reformat data
60
	for (int i = 1 ; i < data.size() ; i++) {
61
		def h = data[i]
62
		def style = [:] // create style entry
63
		String s = h[0];
64
		row_styles[/$s/] = style // with a regexp pattern as key
65
				
66
		// fill the style
67
		for (int j = 1 ; j < h.size() ; j++) {
68
			style[keys[j]] = h[j]
69
		}
70
	}
71
if (debug > 0) {
72
	println "ROW STYLES=$row_styles"
73
}
74

  
75
data = ReadODS.toTable(patternsODSFile, "cols") // read from the "cols" sheet
76
keys = data[0]
77
def col_styles = [:] // reformat data
78

  
79
for (int i = 1 ; i < data.size() ; i++) {
80
	def h = data[i]
81
	def style = [:] // create style entry
82
	String s = h[0];
83
	col_styles[/$s/] = style // with a regexp pattern as key
84
					
85
	// fill the style
86
	for (int j = 1 ; j < h.size() ; j++) {
87
		style[keys[j]] = h[j]
88
	}
89
}
90
if (debug > 0) {
91
	println "COL STYLES=$col_styles"
92
}
93

  
94
ica = editor.getCA()
95
ca = ica.getCA()
96

  
97
// http://txm.sourceforge.net/javadoc/TXM/TBX/org/txm/stat/engine/r/function/CA.html
98

  
99
// SOME DATA
100
rows = ica.getRowNames()
101
rowsinfo = ica.getRowInfos()
102
rowscos2 = ca.getRowCos2()
103
cols = ica.getColNames()
104
colssinfo = ica.getColInfos()
105
colscos2 = ca.getColCos2()
106
D1 = ica.getFirstDimension() -1;
107
D2 = ica.getSecondDimension() -1;
108

  
109
// create some AWT shapes for replacement
110
shapes = new HashMap<String, Shape>();
111
// dimensions scaling factor (the same used in default theme for the replaced shapes have same dimension than non-replaced)
112
float itemShapesScalingFactor = 1.2f
113
shapes["diamond"] = ShapeUtils.createDiamond((float)(itemShapesScalingFactor * 3.4f));
114
shapes["square"] = AbstractRenderer.DEFAULT_SHAPE;
115

  
116
float circleSize = 6.4f * itemShapesScalingFactor;
117
shapes["disk"] = new Ellipse2D.Float((float)(-circleSize / 2), (float)(-circleSize / 2), circleSize, circleSize);
118

  
119
shapes["triangle"] = ShapeUtils.createUpTriangle((float)(itemShapesScalingFactor * 3.2f));
120

  
121
//shapes["star"] = AbstractRenderer.DEFAULT_SHAPE;
122
//shapes["circle"] = AbstractRenderer.DEFAULT_SHAPE;
123

  
124

  
125
println "SHAPES=$shapes"
126

  
127

  
128
// styles per col index in dataset
129
// set col label
130
colLabelStyle = new HashMap<Integer, String>();
131
// set col visibility
132
colHiddenStyle = new HashSet<Integer>(); // true false
133
// set col font size
134
colFontSizeStyle = new HashMap<Integer, Float>();
135
// set col font color
136
colFontColorStyle = new HashMap<Integer, Color>();
137
// set col font family
138
colFontFamilyStyle = new HashMap<Integer, String>();
139
// set col points size
140
colPointSizeStyle = new HashMap<Integer, Double>();
141
// set col points RGBA color
142
colPointColorStyle = new HashMap<Integer, Color>();
143
// set col points shape (circle, square, triangle, ... + color ? + size ?) -> expert
144
colPointShapeStyle = new HashMap<Integer, Shape>(); // circle, square, triangle, etc.
145
// set col font style (1 = bold, 2 = italic, 3 = bold + italic)
146
colFontStyleStyle = new HashMap<Integer, Integer>();
147

  
148

  
149
// set row label
150
rowLabelStyle = new HashMap<Integer, String>();
151
// set row visibility
152
rowHiddenStyle = new HashSet<Integer>(); // true false
153
// set row font size
154
rowFontSizeStyle = new HashMap<Integer, Float>();
155
// set row font size
156
rowFontColorStyle = new HashMap<Integer, Color>();
157
// set row font size
158
rowFontFamilyStyle = new HashMap<Integer, String>();
159
// set row points size
160
rowPointSizeStyle = new HashMap<Integer, Double>();
161
// set row points RGBA color
162
rowPointColorStyle = new HashMap<Integer, Color>();
163
// set row points shape (circle, square, triangle, ... + color ? + size ?) -> expert
164
rowPointShapeStyle = new HashMap<Integer, Shape>(); // circle, square, triangle, etc.
165
// set row font style (1 = bold, 2 = italic, 3 = bold + italic)
166
rowFontStyleStyle = new HashMap<Integer, Integer>();
167

  
168
// prepare col style data for the dataset
169
for (int i = 0 ; i < cols.length ; i++) {
170
	for (def p : col_styles.keySet()) {
171
		if (cols[i] ==~ p) {
172
			def style = col_styles[p]
173
			if (style["label-replacement"] != null && style["label-replacement"].length() > 0) {
174
				colLabelStyle[i] = style["label-replacement"]
175
			}
176
			if (style["hidden"] != null && style["hidden"].toUpperCase() == "T") {
177
				colHiddenStyle << i
178
			}
179
			if (style["shape-size"] != null && style["shape-size"].length() > 0) {
180
				colPointSizeStyle[i] = Double.parseDouble(style["shape-size"])
181
			}
182
			if (style["shape-color"] != null && style["shape-color"].length() > 0 ) {
183
				colPointColorStyle[i] = rgbaStringToColor(style["shape-color"])
184
			}
185
			if (style["shape-replacement"] != null && shapes.containsKey(style["shape-replacement"])) {
186
				colPointShapeStyle[i] = shapes[style["shape-replacement"]]
187
			}
188
			if (style["label-size"] != null && style["label-size"].length() > 0) {
189
				colFontSizeStyle[i] = Float.parseFloat(style["label-size"])
190
			}
191
			if (style["label-color"] != null && style["label-color"].length() > 0) {
192
				colFontColorStyle[i] = rgbaStringToColor(style["label-color"])
193
			}
194
			if (style["label-font-family"] != null && style["label-font-family"].length() > 0) {
195
				colFontFamilyStyle[i] = style["label-font-family"]
196
			}
197
			if (style["label-style"] != null && style["label-style"].length() > 0) {
198
				colFontStyleStyle[i] = Integer.parseInt(style["label-style"])
199
			}
200
			
201
		}
202
	}
203
}
204
if (debug > 0) {
205
	println "COL COL=$colPointColorStyle"
206
	println "COL SHP=$colPointShapeStyle"
207
	println "COL LAB=$colLabelStyle"
208
	println "COL FONT-SIZ=$colFontSizeStyle"
209
	println "COL SIZ=$colPointSizeStyle"
210
	println "COL VIZ=$colHiddenStyle"
211
	println "COL STYLE=$colFontStyleStyle"
212
}
213

  
214
// prepare row style data for the dataset
215
for (int i = 0 ; i < rows.length ; i++) {
216
	for (def p : row_styles.keySet()) {
217
		if (rows[i] ==~ p) {
218
			def style = row_styles[p]
219
			if (style["hidden"] != null && style["hidden"].toUpperCase() == "T") {
220
				rowHiddenStyle << i
221
			}
222
			if (style["label-replacement"] != null && style["label-replacement"].length() > 0) {
223
				rowLabelStyle[i] = style["label-replacement"]
224
			}
225
			if (style["shape-size"] != null && style["shape-size"].length() > 0) {
226
				rowPointSizeStyle[i] = Double.parseDouble(style["shape-size"])
227
			}
228
			if (style["shape-color"] != null && style["shape-color"].length() > 0 ) {
229
				rowPointColorStyle[i] = rgbaStringToColor(style["shape-color"])
230
			}
231
			if (style["shape-replacement"] != null && shapes.containsKey(style["shape-replacement"])) {
232
				rowPointShapeStyle[i] = shapes[style["shape-replacement"]]
233
			}
234
			if (style["label-size"] != null && style["label-size"].length() > 0) {
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff