Bonjour,
Dans le cadre d'une application devant traiter les données d'une carte electronique, je dois afficher les données renvoyées dans un graphe.
Mon problème est le temps de traitement, dans JFreeChart, d'un createXYLineChart.
En effet sans le graphe j'ai un temps de traitement de 4/5 milliseconde qui correspond bien au envoie de trame de ma carte qui est d'environ 4/5 ms aussi et j'obtiens des perfommances stable (environ 15000 trames traitées en 1 minute).
Avec le graphe de JFreeChart, c'est l'hemorragie, sur la premiere minute je suis à environ 9/10 ms pour traiter et afficher un trame, soit le double, et ensuite cela décroit rapidement pour atteindre environ 40ms par trame au bout de 5 minutes...

Je m'attendais à un perte de performances, mais la c'est beaucoup trop.

De plus au bout d'un certain temps (environ 2h), j'arrive à consommer toute la mémoire et à planter mon application.

J'ai essayer, au niveau de l'affichage de retirer les points pour garder un affichage de la derniere minute mais la c'est catastrophique, les performances sont très mauvaise (environ 30ms par trames au bout d'une minute) et en plus j'ai des declenchement d'exception sur les series au niveau des index.


Je cherche une autre solution pour afficher mes données soit afficher 2 courbes sur 1 graphe, quelqu'un aurai une idée pour afficher un si grand nombre de "point"?

On va surement me demander le code alors le voilà:
Déclaration du graphe:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
private JFreeChart getJFreeChart() {
		if(jFreeChart==null){
			jFreeChart=ChartFactory.createXYLineChart("Résultat", "Temps (sec)", "Volt", gestionnaire.getXYDataset(), PlotOrientation.VERTICAL, true, true, true);
			XYPlot xyplot = (XYPlot)jFreeChart.getPlot();
			xyplot.setDomainPannable(true);
	        xyplot.setRangePannable(true);
	        xyplot.setDomainZeroBaselineVisible(true);
	        xyplot.setRangeZeroBaselineVisible(true);
	        XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)xyplot.getRenderer();
	        xylineandshaperenderer.setBaseShapesVisible(false);
	        xylineandshaperenderer.setBaseShapesFilled(true);
	        xylineandshaperenderer.setDrawOutlines(true);
		}
		return jFreeChart;
	}
Déclaration du XYDataset et des series:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
	/**
         * Fonction pour créer le XYDataSet
         * @return
         */
	public XYDataset getXYDataset() {
		if(xyDataSet==null){
			XYSeriesCollection collection= new XYSeriesCollection();
			collection.addSeries(this.getPointSerieCapteur1());
			collection.addSeries(this.getPointSerieCapteur2());
			//collection.addSeries(this.getPointSerieSommeVin());
			xyDataSet=collection;
		}
		return xyDataSet;
	}
	/**
         * Fonction pour créer la serie de point du capteur1
         * @return
         */
	public XYSeries getPointSerieCapteur1() {
		if(pointSerieCapteur1==null){
			pointSerieCapteur1 = new XYSeries("Capteur1");
		}
		return pointSerieCapteur1;
	}
	/**
         * Fonction pour créer la serie de point du capteur2
         * @return
         */
	public XYSeries getPointSerieCapteur2() {
		if(pointSerieCapteur2==null){
			pointSerieCapteur2 = new XYSeries("Capteur2");
		}
		return pointSerieCapteur2;
	}
Déclaration de l'objet de reception, traitement et affichages des données:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
 
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TooManyListenersException;
 
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
 
import com.sun.comm.Win32Driver;
 
public class CommCarteReception implements SerialPortEventListener {
 
	private ConfigConnexionCarte 	config=null;
	private Win32Driver 			w32Driver=null;
	private CommPortIdentifier 		portId=null;
	private SerialPort 				serialPort=null;
	private BufferedReader 			fluxLecture=null;
	private GestPesage 				gestionnaire=null;
	private BufferedWriter			fluxFichierEcriture=null;
	private long 					debut=0;
	private long 					debutSave=0;
	private double 					tempsCurrent=0;
	private long 					current=0;
 
	private String					trame=null;
	private String					capteur1=null;
	private String					capteur2=null;
	private double 					vin1=0.0;
	private double 					vin2=0.0;
 
	private Calendar 				dateNow=null;
	private String 					anFichier=null;
	private String 					moisFichier=null;
	private String 					jourFichier=null;
	private String 					heureFichier=null;
	private String 					minuteFichier=null;
	private String 					secondeFichier=null;
 
	//paramètres de configuration de la carte
	private String aog1=null;
	private String fga1=null;
	private String foa1=null;
	private String feg1=null;
	private String coarseOffset1=null;
	private String aog2=null;
	private String fga2=null;
	private String foa2=null;
	private String feg2=null;
	private String coarseOffset2=null;
 
	/**
         * Constructeur
         * @param conf
         * @param gest
         */
	public CommCarteReception(ConfigConnexionCarte conf,GestPesage gest){
		config=conf;
		gestionnaire=gest;
		aog1=gest.getPga().getaogPGA1();
		fga1=gest.getPga().getfgaPGA1();
		foa1=gest.getPga().getfoaPGA1();
		feg1=gest.getPga().getfegPGA1();
		coarseOffset1=gest.getPga().getcoarseOffsetPGA1();
		aog2=gest.getPga().getaogPGA2();
		fga2=gest.getPga().getfgaPGA2();
		foa2=gest.getPga().getfoaPGA2();
		feg2=gest.getPga().getfegPGA2();
		coarseOffset2=gest.getPga().getcoarseOffsetPGA2();
		w32Driver = new Win32Driver();
		w32Driver.initialize();
		debut=System.currentTimeMillis();
		debutSave=debut;
		dateNow=new GregorianCalendar();
		try {
			portId = CommPortIdentifier.getPortIdentifier(config.getPortCom());
			serialPort = (SerialPort) portId.open("FGEPesage", 2000);
			fluxFichierEcriture=new BufferedWriter(new FileWriter(this.getNow(),true));
			fluxLecture =new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
			serialPort.addEventListener(this);
			serialPort.notifyOnDataAvailable(true);
			serialPort.setSerialPortParams(config.getBauds(),config.getDataBit(),config.getBitStop(),config.getParite());
		}catch (NoSuchPortException nspe) {
			nspe.printStackTrace();
		}catch (PortInUseException piue) {
			piue.printStackTrace();
		}catch (IOException ioe) {
			ioe.printStackTrace();
		}catch (TooManyListenersException tmle) {
			tmle.printStackTrace();
		}catch (UnsupportedCommOperationException ucoe) {
			ucoe.printStackTrace();
		}
	}
//LISTENER
	/**
         * Listener de port com
         */
	@Override
	public void serialEvent(SerialPortEvent event) {
 
		//gestion des événements sur le port :
		//on ne fait rien sauf quand les données sont disponibles
		switch (event.getEventType()) {
			case SerialPortEvent.BI :
			case SerialPortEvent.OE :
			case SerialPortEvent.FE :
			case SerialPortEvent.PE :
			case SerialPortEvent.CD :
			case SerialPortEvent.CTS :
			case SerialPortEvent.DSR :
			case SerialPortEvent.RI :
			case SerialPortEvent.OUTPUT_BUFFER_EMPTY :
				break;
			case SerialPortEvent.DATA_AVAILABLE :
				try {
					//lecture du buffer et affichage
					trame = (String) fluxLecture.readLine();
					if(this.checkSum(trame)){
						capteur1=trame.substring(16, 20);
						capteur2=trame.substring(21, 25);
						current=System.currentTimeMillis();
						tempsCurrent=(current-debut)/1000.0;
						vin1=this.gestionnaire.getVin(this.signerDecimal(capteur1), aog1, fga1, foa1, feg1, coarseOffset1);
						vin2=this.gestionnaire.getVin(this.signerDecimal(capteur2), aog2, fga2, foa2, feg2, coarseOffset2);
						gestionnaire.getPointSerieCapteur1().add(tempsCurrent,vin1);
						gestionnaire.getPointSerieCapteur2().add(tempsCurrent,vin2);
						fluxFichierEcriture.write(trame);
						fluxFichierEcriture.newLine();
						if((current)-debutSave>=60000){
							debutSave=current;
							fluxFichierEcriture.flush();
							fluxFichierEcriture.close();
							fluxFichierEcriture=new BufferedWriter(new FileWriter(this.getNow(),true));
						}
					}
				}catch (IOException ioe) {
					ioe.printStackTrace();
				}
			break;
		}
	}
	/**
         * Fonction pour arreter la capture des données de la carte
         */
	public void stop(){
		try {
			fluxFichierEcriture.close();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		serialPort.close();
 
	}
	/**
         * Fonction pour formatter le nom du fichier
         * @param arg
         * @return
         */
	private String formatZero(String arg){
		if(arg.length()<2){
			arg="0"+arg;
		}
		return arg;
	}
	/**
         * Fonction pour formatter le nom de fichier de svg 
         * @return
         */
	private String getNow(){
		String now=null;
 
		dateNow=dateNow.getInstance();
		anFichier=dateNow.get(Calendar.YEAR)+"";
		moisFichier=this.formatZero((dateNow.get(Calendar.MONTH)+1)+"");
		jourFichier=this.formatZero(dateNow.get(Calendar.DAY_OF_MONTH)+"");
		heureFichier=this.formatZero(dateNow.get(Calendar.HOUR_OF_DAY)+"");
		minuteFichier=this.formatZero(dateNow.get(Calendar.MINUTE)+"");
		secondeFichier=this.formatZero(dateNow.get(Calendar.SECOND)+"");
		now=anFichier+"-"+moisFichier+"-"+jourFichier+"-"+heureFichier+"-"+minuteFichier+"-"+secondeFichier+".svg";
		return now;
	}
	/**
         * Converti la sortie des capteurs d'un decimal à un decimal signé
         * @param arg
         * @return
         */
	public short signerDecimal(String arg){
		return (short)Integer.parseInt(arg,16);
	}
	/**
         * Test le checkSum
         * @param arg
         * @return
         */
	private boolean checkSum(String arg){
		int 	sumDonne=0;
		int 	sum=0;
		String 	ligneChar=null;
		if(arg!=null){
			if(arg.length()==33){
				sumDonne=Integer.parseInt(arg.substring(26, 31));
				ligneChar=arg.substring(0, 26);
				for(int cpt=0;cpt<ligneChar.length();cpt++){
					sum=sum+ligneChar.charAt(cpt);
				}
				sum=65535-sum;
				if(sumDonne==sum){
					return true;
				}
			}
		}
		return false;
	}
}
Exemple:
Je fais 1 nouveau fichier de sauvegarde toute les minutes.
En "commentant" les 2 lignes qui ajoutent les "points" sur le graph, mes fichiers de sauvegarde font environ 520Ko.
En les laissant, le premier fichier fais environ 267Ko, le second 123Ko..., jusqu'à se "stabiliser" à environ 50Ko.

Merci d'avance