1 /*
2 / DialogsGraph.cpp
3 / graphics dialog classes
4 /
5 / version 1.7, 2013 May 8
6 /
7 / Author: Sandro Furieri a-furieri@lqt.it
8 /
9 / Copyright (C) 2010-2013 Alessandro Furieri
10 /
11 / This program is free software: you can redistribute it and/or modify
12 / it under the terms of the GNU General Public License as published by
13 / the Free Software Foundation, either version 3 of the License, or
14 / (at your option) any later version.
15 /
16 / This program is distributed in the hope that it will be useful,
17 / but WITHOUT ANY WARRANTY; without even the implied warranty of
18 / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 / GNU General Public License for more details.
20 /
21 / You should have received a copy of the GNU General Public License
22 / along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /
24 */
25
26 #include "Classdef.h"
27
28 #include "wx/spinctrl.h"
29 #include "wx/filedlg.h"
30 #include "wx/filename.h"
31 #include "wx/colordlg.h"
32 #include "wx/clipbrd.h"
33
34 #include <gaiagraphics.h>
35
36 #if defined(_WIN32) || defined (__MINGW32__)
37 #define FORMAT_64 "%I64d"
38 #else
39 #define FORMAT_64 "%lld"
40 #endif
41
Create(MyFrame * parent,wxString & table,wxString & column,int null_count,int text_count,int integer_count,int real_count,int blob_count,double min,double max,double avg,double stddev_pop,double stddev_samp,double var_pop,double var_samp,int distinct_values)42 bool ColumnStatsDialog::Create(MyFrame * parent, wxString & table,
43 wxString & column, int null_count,
44 int text_count, int integer_count,
45 int real_count, int blob_count, double min,
46 double max, double avg, double stddev_pop,
47 double stddev_samp, double var_pop,
48 double var_samp, int distinct_values)
49 {
50 //
51 // creating the dialog
52 //
53 MainFrame = parent;
54 Table = table;
55 Column = column;
56 NullValues = null_count;
57 TextValues = text_count;
58 IntegerValues = integer_count;
59 RealValues = real_count;
60 BlobValues = blob_count;
61 Min = min;
62 Max = max;
63 Avg = avg;
64 StdDevPop = stddev_pop;
65 StdDevSamp = stddev_samp;
66 VarPop = var_pop;
67 VarSamp = var_samp;
68 DistinctValues = distinct_values;
69 if (wxDialog::Create(parent, wxID_ANY, wxT("Column statistic snapshot")) ==
70 false)
71 return false;
72 // populates individual controls
73 CreateControls();
74 // sets dialog sizer
75 GetSizer()->Fit(this);
76 GetSizer()->SetSizeHints(this);
77 // centers the dialog window
78 Centre();
79 return true;
80 }
81
CreateControls()82 void ColumnStatsDialog::CreateControls()
83 {
84 //
85 // creating individual control and setting initial values
86 //
87 char dummy[256];
88 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
89 this->SetSizer(topSizer);
90 wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
91 topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
92 // First row: TABLE name
93 wxBoxSizer *tableSizer = new wxBoxSizer(wxHORIZONTAL);
94 boxSizer->Add(tableSizer, 0, wxALIGN_RIGHT | wxALL, 0);
95 wxStaticText *tableLabel =
96 new wxStaticText(this, wxID_STATIC, wxT("&Table name:"));
97 tableSizer->Add(tableLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
98 wxTextCtrl *tableCtrl = new wxTextCtrl(this, wxID_ANY, Table,
99 wxDefaultPosition, wxSize(350, 22),
100 wxTE_READONLY);
101 tableCtrl->Enable(false);
102 tableSizer->Add(tableCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
103 // second row: COLUMN name
104 wxBoxSizer *colSizer = new wxBoxSizer(wxHORIZONTAL);
105 boxSizer->Add(colSizer, 0, wxALIGN_RIGHT | wxALL, 0);
106 wxStaticText *colLabel =
107 new wxStaticText(this, wxID_STATIC, wxT("&Column name:"));
108 colSizer->Add(colLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
109 wxTextCtrl *colCtrl = new wxTextCtrl(this, wxID_ANY, Column,
110 wxDefaultPosition, wxSize(350, 22),
111 wxTE_READONLY);
112 colCtrl->Enable(false);
113 colSizer->Add(colCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
114 // third row: total rows
115 wxBoxSizer *rowSizer = new wxBoxSizer(wxHORIZONTAL);
116 boxSizer->Add(rowSizer, 0, wxALIGN_RIGHT | wxALL, 0);
117 wxStaticText *rowLabel =
118 new wxStaticText(this, wxID_STATIC, wxT("&Total values:"));
119 rowSizer->Add(rowLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
120 sprintf(dummy, "%d",
121 NullValues + TextValues + IntegerValues + RealValues + BlobValues);
122 wxString rows = wxString::FromUTF8(dummy);
123 wxTextCtrl *rowCtrl = new wxTextCtrl(this, wxID_ANY, rows,
124 wxDefaultPosition, wxSize(350, 22),
125 wxTE_READONLY);
126 rowCtrl->Enable(false);
127 rowSizer->Add(rowCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
128 if (NullValues > 0)
129 {
130 // NULL values count
131 wxBoxSizer *nullSizer = new wxBoxSizer(wxHORIZONTAL);
132 boxSizer->Add(nullSizer, 0, wxALIGN_RIGHT | wxALL, 0);
133 wxStaticText *nullLabel =
134 new wxStaticText(this, wxID_STATIC, wxT("&NULL values:"));
135 nullSizer->Add(nullLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
136 sprintf(dummy, "%d", NullValues);
137 wxString nulls = wxString::FromUTF8(dummy);
138 wxTextCtrl *nullCtrl = new wxTextCtrl(this, wxID_ANY, nulls,
139 wxDefaultPosition, wxSize(350, 22),
140 wxTE_READONLY);
141 nullCtrl->Enable(false);
142 nullSizer->Add(nullCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
143 }
144 if (TextValues > 0)
145 {
146 // TEXT values count
147 wxBoxSizer *textSizer = new wxBoxSizer(wxHORIZONTAL);
148 boxSizer->Add(textSizer, 0, wxALIGN_RIGHT | wxALL, 0);
149 wxStaticText *textLabel =
150 new wxStaticText(this, wxID_STATIC, wxT("&TEXT values:"));
151 textSizer->Add(textLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
152 sprintf(dummy, "%d", TextValues);
153 wxString texts = wxString::FromUTF8(dummy);
154 wxTextCtrl *textCtrl = new wxTextCtrl(this, wxID_ANY, texts,
155 wxDefaultPosition, wxSize(350, 22),
156 wxTE_READONLY);
157 textCtrl->Enable(false);
158 textSizer->Add(textCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
159 }
160 if (IntegerValues > 0)
161 {
162 // INTEGER values count
163 wxBoxSizer *intSizer = new wxBoxSizer(wxHORIZONTAL);
164 boxSizer->Add(intSizer, 0, wxALIGN_RIGHT | wxALL, 0);
165 wxStaticText *intLabel =
166 new wxStaticText(this, wxID_STATIC, wxT("&INTEGER values:"));
167 intSizer->Add(intLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
168 sprintf(dummy, "%d", IntegerValues);
169 wxString ints = wxString::FromUTF8(dummy);
170 wxTextCtrl *intCtrl = new wxTextCtrl(this, wxID_ANY, ints,
171 wxDefaultPosition, wxSize(350, 22),
172 wxTE_READONLY);
173 intCtrl->Enable(false);
174 intSizer->Add(intCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
175 }
176 if (RealValues > 0)
177 {
178 // REAL values count
179 wxBoxSizer *realSizer = new wxBoxSizer(wxHORIZONTAL);
180 boxSizer->Add(realSizer, 0, wxALIGN_RIGHT | wxALL, 0);
181 wxStaticText *realLabel =
182 new wxStaticText(this, wxID_STATIC, wxT("&REAL values:"));
183 realSizer->Add(realLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
184 sprintf(dummy, "%d", RealValues);
185 wxString reals = wxString::FromUTF8(dummy);
186 wxTextCtrl *realCtrl = new wxTextCtrl(this, wxID_ANY, reals,
187 wxDefaultPosition, wxSize(350, 22),
188 wxTE_READONLY);
189 realCtrl->Enable(false);
190 realSizer->Add(realCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
191 }
192 if (BlobValues > 0)
193 {
194 // BLOB values count
195 wxBoxSizer *blobSizer = new wxBoxSizer(wxHORIZONTAL);
196 boxSizer->Add(blobSizer, 0, wxALIGN_RIGHT | wxALL, 0);
197 wxStaticText *blobLabel =
198 new wxStaticText(this, wxID_STATIC, wxT("&BLOB values:"));
199 blobSizer->Add(blobLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
200 sprintf(dummy, "%d", BlobValues);
201 wxString blobs = wxString::FromUTF8(dummy);
202 wxTextCtrl *blobCtrl = new wxTextCtrl(this, wxID_ANY, blobs,
203 wxDefaultPosition, wxSize(350, 22),
204 wxTE_READONLY);
205 blobCtrl->Enable(false);
206 blobSizer->Add(blobCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
207 }
208 // statistical group box
209 wxStaticBox *statBox = new wxStaticBox(this, wxID_STATIC,
210 wxT("Data distribution snapshot"),
211 wxDefaultPosition,
212 wxDefaultSize);
213 wxBoxSizer *statSizer = new wxStaticBoxSizer(statBox, wxVERTICAL);
214 boxSizer->Add(statSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
215 // distinct values count
216 wxBoxSizer *distSizer = new wxBoxSizer(wxHORIZONTAL);
217 statSizer->Add(distSizer, 0, wxALIGN_CENTER | wxALL, 0);
218 wxStaticText *distLabel =
219 new wxStaticText(this, wxID_STATIC, wxT("&DISTINCT values:"));
220 distSizer->Add(distLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
221 sprintf(dummy, "%d", DistinctValues);
222 wxString dists = wxString::FromUTF8(dummy);
223 wxTextCtrl *distCtrl = new wxTextCtrl(this, wxID_ANY, dists,
224 wxDefaultPosition, wxSize(150, 22),
225 wxTE_READONLY);
226 distCtrl->Enable(false);
227 distSizer->Add(distCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
228
229 if ((IntegerValues + RealValues) > 1)
230 {
231 // statistic analysis: MinMax range
232 wxStaticBox *rangeBox = new wxStaticBox(this, wxID_STATIC,
233 wxT("Data range"),
234 wxDefaultPosition,
235 wxDefaultSize);
236 wxBoxSizer *rngSizer = new wxStaticBoxSizer(rangeBox, wxVERTICAL);
237 statSizer->Add(rngSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
238 wxBoxSizer *minMaxSizer = new wxBoxSizer(wxHORIZONTAL);
239 rngSizer->Add(minMaxSizer, 0, wxALIGN_CENTER | wxALL, 0);
240 wxStaticText *minLabel =
241 new wxStaticText(this, wxID_STATIC, wxT("&Min:"));
242 minMaxSizer->Add(minLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
243 sprintf(dummy, "%1.18f", Min);
244 CleanDecimals(dummy);
245 wxString min = wxString::FromUTF8(dummy);
246 wxTextCtrl *minCtrl = new wxTextCtrl(this, wxID_ANY, min,
247 wxDefaultPosition, wxSize(150, 22),
248 wxTE_READONLY);
249 minCtrl->Enable(false);
250 minMaxSizer->Add(minCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
251 wxStaticText *maxLabel =
252 new wxStaticText(this, wxID_STATIC, wxT("&Max:"));
253 minMaxSizer->Add(maxLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
254 sprintf(dummy, "%1.18f", Max);
255 CleanDecimals(dummy);
256 wxString max = wxString::FromUTF8(dummy);
257 wxTextCtrl *maxCtrl = new wxTextCtrl(this, wxID_ANY, max,
258 wxDefaultPosition, wxSize(150, 22),
259 wxTE_READONLY);
260 maxCtrl->Enable(false);
261 minMaxSizer->Add(maxCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
262 // statistic analysis: Average
263 wxBoxSizer *avgSizer = new wxBoxSizer(wxHORIZONTAL);
264 statSizer->Add(avgSizer, 0, wxALIGN_CENTER | wxALL, 0);
265 wxStaticText *avgLabel =
266 new wxStaticText(this, wxID_STATIC, wxT("&Average:"));
267 avgSizer->Add(avgLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
268 sprintf(dummy, "%1.4f", Avg);
269 CleanDecimals(dummy);
270 wxString avg = wxString::FromUTF8(dummy);
271 wxTextCtrl *avgCtrl = new wxTextCtrl(this, wxID_ANY, avg,
272 wxDefaultPosition, wxSize(150, 22),
273 wxTE_READONLY);
274 avgCtrl->Enable(false);
275 avgSizer->Add(avgCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
276 // statistic analysis: Standard Deviation
277 wxStaticBox *stdDevBox = new wxStaticBox(this, wxID_STATIC,
278 wxT("Standard deviation"),
279 wxDefaultPosition,
280 wxDefaultSize);
281 wxBoxSizer *stdSizer = new wxStaticBoxSizer(stdDevBox, wxVERTICAL);
282 statSizer->Add(stdSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
283 wxBoxSizer *stdDevSizer = new wxBoxSizer(wxHORIZONTAL);
284 stdSizer->Add(stdDevSizer, 0, wxALIGN_CENTER | wxALL, 0);
285 wxStaticText *devPopLabel =
286 new wxStaticText(this, wxID_STATIC, wxT("&Pop:"));
287 stdDevSizer->Add(devPopLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
288 sprintf(dummy, "%1.4f", StdDevPop);
289 CleanDecimals(dummy);
290 wxString stdPop = wxString::FromUTF8(dummy);
291 wxTextCtrl *stdPopCtrl = new wxTextCtrl(this, wxID_ANY, stdPop,
292 wxDefaultPosition, wxSize(150,
293 22),
294 wxTE_READONLY);
295 stdPopCtrl->Enable(false);
296 stdDevSizer->Add(stdPopCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
297 wxStaticText *stdSampLabel =
298 new wxStaticText(this, wxID_STATIC, wxT("&Samp:"));
299 stdDevSizer->Add(stdSampLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
300 sprintf(dummy, "%1.4f", StdDevSamp);
301 CleanDecimals(dummy);
302 wxString stdSamp = wxString::FromUTF8(dummy);
303 wxTextCtrl *stdSampCtrl = new wxTextCtrl(this, wxID_ANY, stdSamp,
304 wxDefaultPosition, wxSize(150,
305 22),
306 wxTE_READONLY);
307 stdSampCtrl->Enable(false);
308 stdDevSizer->Add(stdSampCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
309 // statistic analysis: Variance
310 wxStaticBox *varBox = new wxStaticBox(this, wxID_STATIC,
311 wxT("Variance"),
312 wxDefaultPosition,
313 wxDefaultSize);
314 wxBoxSizer *varianceSizer = new wxStaticBoxSizer(varBox, wxVERTICAL);
315 statSizer->Add(varianceSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
316 wxBoxSizer *varSizer = new wxBoxSizer(wxHORIZONTAL);
317 varianceSizer->Add(varSizer, 0, wxALIGN_CENTER | wxALL, 0);
318 wxStaticText *varPopLabel =
319 new wxStaticText(this, wxID_STATIC, wxT("&Pop:"));
320 varSizer->Add(varPopLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
321 sprintf(dummy, "%1.4f", VarPop);
322 CleanDecimals(dummy);
323 wxString varPop = wxString::FromUTF8(dummy);
324 wxTextCtrl *varPopCtrl = new wxTextCtrl(this, wxID_ANY, varPop,
325 wxDefaultPosition, wxSize(150,
326 22),
327 wxTE_READONLY);
328 varPopCtrl->Enable(false);
329 varSizer->Add(varPopCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
330 wxStaticText *varSampLabel =
331 new wxStaticText(this, wxID_STATIC, wxT("&Samp:"));
332 varSizer->Add(varSampLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
333 sprintf(dummy, "%1.4f", VarSamp);
334 CleanDecimals(dummy);
335 wxString varSamp = wxString::FromUTF8(dummy);
336 wxTextCtrl *varSampCtrl = new wxTextCtrl(this, wxID_ANY, varSamp,
337 wxDefaultPosition, wxSize(150,
338 22),
339 wxTE_READONLY);
340 varSampCtrl->Enable(false);
341 varSizer->Add(varSampCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
342 }
343 // buttons
344 wxBoxSizer *buttonBox = new wxBoxSizer(wxHORIZONTAL);
345 boxSizer->Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
346 wxButton *chart = new wxButton(this, ID_STAT_CHART, wxT("&Show chart"));
347 buttonBox->Add(chart, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
348 wxButton *exit = new wxButton(this, wxID_OK, wxT("&Exit"));
349 buttonBox->Add(exit, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
350 // appends event handler for OK button
351 Connect(ID_STAT_CHART, wxEVT_COMMAND_BUTTON_CLICKED,
352 (wxObjectEventFunction) & ColumnStatsDialog::OnShowChart);
353 Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
354 (wxObjectEventFunction) & ColumnStatsDialog::OnExit);
355 }
356
CleanDecimals(char * str)357 void ColumnStatsDialog::CleanDecimals(char *str)
358 {
359 // suppressing not significative decimal digits
360 int i;
361 int len = strlen(str);
362 for (i = len - 1; i >= 0; i--)
363 {
364 if (str[i] == '0')
365 str[i] = '\0';
366 else
367 break;
368 }
369 len = strlen(str);
370 if (str[len - 1] == '.')
371 str[len - 1] = '\0';
372 }
373
OnShowChart(wxCommandEvent & WXUNUSED (event))374 void ColumnStatsDialog::OnShowChart(wxCommandEvent & WXUNUSED(event))
375 {
376 //
377 // showing a chart:
378 //
379 bool numeric = false;
380 StatsChartDialog dlg;
381 if (IntegerValues > 0 || RealValues > 0)
382 numeric = true;
383 dlg.Create(this, MainFrame, Table, Column, numeric, Min, Max);
384 dlg.ShowModal();
385 }
386
OnExit(wxCommandEvent & WXUNUSED (event))387 void ColumnStatsDialog::OnExit(wxCommandEvent & WXUNUSED(event))
388 {
389 //
390 // all done:
391 //
392 wxDialog::EndModal(wxID_OK);
393 }
394
Create(ColumnStatsDialog * parent,MyFrame * granny,wxString & table,wxString & column,bool numeric,double min,double max)395 bool StatsChartDialog::Create(ColumnStatsDialog * parent, MyFrame * granny,
396 wxString & table, wxString & column, bool numeric,
397 double min, double max)
398 {
399 //
400 // creating the dialog
401 //
402 MainFrame = granny;
403 Table = table;
404 Column = column;
405 NumericData = numeric;
406 Min = min;
407 Max = max;
408 if (wxDialog::Create(parent, wxID_ANY, wxT("Chart preview")) == false)
409 return false;
410 // populates individual controls
411 CreateControls();
412 // sets dialog sizer
413 GetSizer()->Fit(this);
414 GetSizer()->SetSizeHints(this);
415 // centers the dialog window
416 Centre();
417 return true;
418 }
419
CreateControls()420 void StatsChartDialog::CreateControls()
421 {
422 //
423 // creating individual control and setting initial values
424 //
425 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
426 this->SetSizer(topSizer);
427 wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
428 topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
429 // First row: TABLE name
430 wxBoxSizer *tableSizer = new wxBoxSizer(wxHORIZONTAL);
431 boxSizer->Add(tableSizer, 0, wxALIGN_RIGHT | wxALL, 0);
432 wxStaticText *tableLabel =
433 new wxStaticText(this, wxID_STATIC, wxT("&Table name:"));
434 tableSizer->Add(tableLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
435 wxTextCtrl *tableCtrl = new wxTextCtrl(this, wxID_ANY, Table,
436 wxDefaultPosition, wxSize(350, 22),
437 wxTE_READONLY);
438 tableCtrl->Enable(false);
439 tableSizer->Add(tableCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
440 // second row: COLUMN name
441 wxBoxSizer *colSizer = new wxBoxSizer(wxHORIZONTAL);
442 boxSizer->Add(colSizer, 0, wxALIGN_RIGHT | wxALL, 0);
443 wxStaticText *colLabel =
444 new wxStaticText(this, wxID_STATIC, wxT("&Column name:"));
445 colSizer->Add(colLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
446 wxTextCtrl *colCtrl = new wxTextCtrl(this, wxID_ANY, Column,
447 wxDefaultPosition, wxSize(350, 22),
448 wxTE_READONLY);
449 colCtrl->Enable(false);
450 colSizer->Add(colCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
451 // third row: Chart params
452 wxStaticBox *optBox = new wxStaticBox(this, wxID_STATIC,
453 wxT("Chart settings"),
454 wxDefaultPosition,
455 wxDefaultSize);
456 wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxVERTICAL);
457 boxSizer->Add(optSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
458 wxBoxSizer *chartSizer = new wxBoxSizer(wxHORIZONTAL);
459 optSizer->Add(chartSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
460 wxString type[3];
461 type[0] = wxT("&Histogram");
462 type[1] = wxT("&Line chart");
463 type[2] = wxT("&Pie chart");
464 TypeCtrl = new wxRadioBox(this, ID_CHART_TYPE,
465 wxT("&Type"),
466 wxDefaultPosition,
467 wxDefaultSize, 3, type, 1, wxRA_SPECIFY_COLS);
468 chartSizer->Add(TypeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
469 TypeCtrl->SetSelection(0);
470 Histogram = true;
471 LineChart = false;
472 PieChart = false;
473 wxString size[5];
474 size[0] = wxT("&256");
475 size[1] = wxT("&512");
476 size[2] = wxT("&1024");
477 size[3] = wxT("&2048");
478 size[4] = wxT("&4196");
479 SizeCtrl = new wxRadioBox(this, ID_CHART_SIZE,
480 wxT("&Dimension [pixels]"),
481 wxDefaultPosition,
482 wxDefaultSize, 5, size, 1, wxRA_SPECIFY_COLS);
483 chartSizer->Add(SizeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
484 SizeCtrl->SetSelection(0);
485 wxBoxSizer *mixSizer = new wxBoxSizer(wxVERTICAL);
486 chartSizer->Add(mixSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
487 wxString mode[2];
488 mode[0] = wxT("&by intervals");
489 mode[1] = wxT("&by unique values");
490 ModeCtrl = new wxRadioBox(this, ID_CHART_MODE,
491 wxT("&Mode"),
492 wxDefaultPosition,
493 wxDefaultSize, 2, mode, 1, wxRA_SPECIFY_COLS);
494 mixSizer->Add(ModeCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
495 if (NumericData == true)
496 {
497 ModeCtrl->SetSelection(0);
498 ByInterval = true;
499 } else
500 {
501 ModeCtrl->SetSelection(1);
502 ModeCtrl->Enable(false);
503 ByInterval = false;
504 }
505 wxBoxSizer *classSizer = new wxBoxSizer(wxHORIZONTAL);
506 mixSizer->Add(classSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
507 wxStaticText *classLabel =
508 new wxStaticText(this, wxID_STATIC, wxT("&Classes:"));
509 classSizer->Add(classLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
510 ClassCtrl = new wxSpinCtrl(this, ID_CHART_CLASS, wxT("10"),
511 wxDefaultPosition, wxSize(80, 20),
512 wxSP_ARROW_KEYS, 2, 1000, 10);
513 classSizer->Add(ClassCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
514 Classes = 10;
515
516 // creating a control to show the Chart preview
517 wxStaticBox *exBox = new wxStaticBox(this, wxID_ANY,
518 wxT("Chart preview"),
519 wxDefaultPosition, wxDefaultSize);
520 wxBoxSizer *showSizer = new wxStaticBoxSizer(exBox, wxHORIZONTAL);
521 boxSizer->Add(showSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
522 ChartShow = new wxStaticBitmap(this, wxID_ANY,
523 wxBitmap(), wxDefaultPosition, wxSize(256,
524 256),
525 wxBORDER_SUNKEN);
526 showSizer->Add(ChartShow, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
527
528 // buttons
529 wxStaticBox *btnBox = new wxStaticBox(this, wxID_STATIC,
530 wxT("Export as"),
531 wxDefaultPosition,
532 wxDefaultSize);
533 wxBoxSizer *btnSizer = new wxStaticBoxSizer(btnBox, wxVERTICAL);
534 showSizer->Add(btnSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
535 wxBoxSizer *buttonBox = new wxBoxSizer(wxVERTICAL);
536 btnSizer->Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
537 wxButton *copy = new wxButton(this, ID_CHART_COPY, wxT("&Copy"));
538 buttonBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
539 wxButton *png = new wxButton(this, ID_CHART_PNG, wxT("&PNG"));
540 buttonBox->Add(png, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
541 wxButton *svg = new wxButton(this, ID_CHART_SVG, wxT("&SVG"));
542 buttonBox->Add(svg, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
543 wxButton *pdf = new wxButton(this, ID_CHART_PDF, wxT("&PDF"));
544 buttonBox->Add(pdf, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
545 wxBoxSizer *exitBox = new wxBoxSizer(wxHORIZONTAL);
546 boxSizer->Add(exitBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
547 wxButton *exit = new wxButton(this, wxID_OK, wxT("&Exit"));
548 exitBox->Add(exit, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
549 // appends event handler for OK button
550 Connect(ID_CHART_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
551 (wxObjectEventFunction) & StatsChartDialog::OnChartCopy);
552 Connect(ID_CHART_PNG, wxEVT_COMMAND_BUTTON_CLICKED,
553 (wxObjectEventFunction) & StatsChartDialog::OnChartPng);
554 Connect(ID_CHART_SVG, wxEVT_COMMAND_BUTTON_CLICKED,
555 (wxObjectEventFunction) & StatsChartDialog::OnChartSvg);
556 Connect(ID_CHART_PDF, wxEVT_COMMAND_BUTTON_CLICKED,
557 (wxObjectEventFunction) & StatsChartDialog::OnChartPdf);
558 Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
559 (wxObjectEventFunction) & StatsChartDialog::OnExit);
560 Connect(ID_CHART_TYPE, wxEVT_COMMAND_RADIOBOX_SELECTED,
561 (wxObjectEventFunction) & StatsChartDialog::OnChartTypeChanged);
562 Connect(ID_CHART_MODE, wxEVT_COMMAND_RADIOBOX_SELECTED,
563 (wxObjectEventFunction) & StatsChartDialog::OnChartModeChanged);
564 Connect(ID_CHART_CLASS, wxEVT_COMMAND_TEXT_UPDATED,
565 (wxObjectEventFunction) & StatsChartDialog::OnChartClassesChanged);
566 // showing the current preview
567 ReloadData();
568 UpdatePreview();
569 }
570
OnChartTypeChanged(wxCommandEvent & WXUNUSED (event))571 void StatsChartDialog::OnChartTypeChanged(wxCommandEvent & WXUNUSED(event))
572 {
573 // chart type radiobox changed
574 switch (TypeCtrl->GetSelection())
575 {
576 case 0:
577 Histogram = true;
578 LineChart = false;
579 PieChart = false;
580 break;
581 case 1:
582 Histogram = false;
583 LineChart = true;
584 PieChart = false;
585 break;
586 case 2:
587 Histogram = false;
588 LineChart = false;
589 PieChart = true;
590 break;
591 };
592 UpdatePreview();
593 }
594
OnChartModeChanged(wxCommandEvent & WXUNUSED (event))595 void StatsChartDialog::OnChartModeChanged(wxCommandEvent & WXUNUSED(event))
596 {
597 // chart mode radiobox changed
598 switch (ModeCtrl->GetSelection())
599 {
600 case 0:
601 ByInterval = true;
602 break;
603 case 1:
604 ByInterval = false;
605 break;
606 };
607 ReloadData();
608 UpdatePreview();
609 }
610
OnChartClassesChanged(wxCommandEvent & WXUNUSED (event))611 void StatsChartDialog::OnChartClassesChanged(wxCommandEvent & WXUNUSED(event))
612 {
613 //
614 // Classes selection changed
615 //
616 Classes = ClassCtrl->GetValue();
617 ReloadData();
618 UpdatePreview();
619 }
620
UpdatePreview()621 void StatsChartDialog::UpdatePreview()
622 {
623 // showing an empty preview chart
624 wxBitmap bmp;
625 ChartShow->SetBitmap(bmp);
626 if (ChartData.IsValid() != true)
627 return;
628
629 // updating the Chart Preview
630 if (ByInterval == true)
631 {
632 if (Histogram == true)
633 DoIntervalHistogram(256, 256, CHART_TARGET_IS_PREVIEW, 8);
634 if (LineChart == true)
635 DoIntervalLineChart(256, 256, CHART_TARGET_IS_PREVIEW, 8);
636 if (PieChart == true)
637 DoIntervalPieChart(256, 256, CHART_TARGET_IS_PREVIEW, 8);
638 } else
639 {
640 if (Histogram == true)
641 DoUniqueHistogram(256, 256, CHART_TARGET_IS_PREVIEW, 8);
642 if (LineChart == true)
643 DoUniqueLineChart(256, 256, CHART_TARGET_IS_PREVIEW, 8);
644 if (PieChart == true)
645 DoUniquePieChart(256, 256, CHART_TARGET_IS_PREVIEW, 8);
646 }
647 }
648
ReloadData()649 void StatsChartDialog::ReloadData()
650 {
651 // reloading Char Data
652 if (ChartData.Check(ByInterval, Classes) == true)
653 return; /* still valid Data */
654
655 ::wxBeginBusyCursor();
656 ChartData.CleanData();
657 if (ByInterval == true)
658 PrepareDataByInterval(Classes);
659 else
660 PrepareDataByUniqueValue(Classes);
661 ::wxEndBusyCursor();
662
663 if (ChartData.IsValid() != true)
664 {
665 wxMessageBox(wxT("Unable to retrieve column data"),
666 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
667 return;
668 }
669 }
670
OnChartCopy(wxCommandEvent & WXUNUSED (event))671 void StatsChartDialog::OnChartCopy(wxCommandEvent & WXUNUSED(event))
672 {
673 // copying the current Chart to the Clipboard
674 int hsize;
675 int vsize;
676 int font_size;
677 if (ChartData.IsValid() != true)
678 return;
679 switch (SizeCtrl->GetSelection())
680 {
681 case 0:
682 hsize = 256;
683 vsize = 256;
684 font_size = 8;
685 break;
686 case 1:
687 hsize = 512;
688 vsize = 512;
689 font_size = 8;
690 break;
691 case 2:
692 hsize = 1024;
693 vsize = 1024;
694 font_size = 10;
695 break;
696 case 3:
697 hsize = 2048;
698 vsize = 2048;
699 font_size = 12;
700 break;
701 case 4:
702 hsize = 4196;
703 vsize = 4196;
704 font_size = 12;
705 break;
706 };
707
708 // exporting the Chart as COPY
709 if (ByInterval == true)
710 {
711 if (Histogram == true)
712 DoIntervalHistogram(hsize, vsize, CHART_TARGET_IS_COPY, font_size);
713 if (LineChart == true)
714 DoIntervalLineChart(hsize, vsize, CHART_TARGET_IS_COPY, font_size);
715 if (PieChart == true)
716 DoIntervalPieChart(hsize, vsize, CHART_TARGET_IS_COPY, font_size);
717 } else
718 {
719 if (Histogram == true)
720 DoUniqueHistogram(hsize, vsize, CHART_TARGET_IS_COPY, font_size);
721 if (LineChart == true)
722 DoUniqueLineChart(hsize, vsize, CHART_TARGET_IS_COPY, font_size);
723 if (PieChart == true)
724 DoUniquePieChart(hsize, vsize, CHART_TARGET_IS_COPY, font_size);
725 }
726 }
727
OnChartPng(wxCommandEvent & WXUNUSED (event))728 void StatsChartDialog::OnChartPng(wxCommandEvent & WXUNUSED(event))
729 {
730 // exporting the current Chart as PNG
731 int hsize;
732 int vsize;
733 int font_size;
734 if (ChartData.IsValid() != true)
735 return;
736 switch (SizeCtrl->GetSelection())
737 {
738 case 0:
739 hsize = 256;
740 vsize = 256;
741 font_size = 8;
742 break;
743 case 1:
744 hsize = 512;
745 vsize = 512;
746 font_size = 8;
747 break;
748 case 2:
749 hsize = 1024;
750 vsize = 1024;
751 font_size = 10;
752 break;
753 case 3:
754 hsize = 2048;
755 vsize = 2048;
756 font_size = 12;
757 break;
758 case 4:
759 hsize = 4196;
760 vsize = 4196;
761 font_size = 12;
762 break;
763 };
764
765 // asking an export path
766 int ret;
767 wxString lastDir;
768 wxString fileList = wxT("PNG Image (*.png)|*.png");
769 wxFileDialog fileDialog(MainFrame, wxT("saving the current Chart as PNG"),
770 wxT(""), wxT("ChartExport"), fileList,
771 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
772 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
773 lastDir = MainFrame->GetLastDirectory();
774 if (lastDir.Len() >= 1)
775 fileDialog.SetDirectory(lastDir);
776 ret = fileDialog.ShowModal();
777 if (ret == wxID_OK)
778 {
779 wxFileName file(fileDialog.GetPath());
780 lastDir = file.GetPath();
781 MainFrame->SetLastDirectory(lastDir);
782 wxString path = file.GetPath();
783 path += file.GetPathSeparator();
784 path += file.GetName();
785 path += wxT(".png");
786 ExportPath = path;
787 } else
788 return;
789
790
791 // exporting the Chart as PNG
792 if (ByInterval == true)
793 {
794 if (Histogram == true)
795 DoIntervalHistogram(hsize, vsize, CHART_TARGET_IS_PNG, font_size);
796 if (LineChart == true)
797 DoIntervalLineChart(hsize, vsize, CHART_TARGET_IS_PNG, font_size);
798 if (PieChart == true)
799 DoIntervalPieChart(hsize, vsize, CHART_TARGET_IS_PNG, font_size);
800 } else
801 {
802 if (Histogram == true)
803 DoUniqueHistogram(hsize, vsize, CHART_TARGET_IS_PNG, font_size);
804 if (LineChart == true)
805 DoUniqueLineChart(hsize, vsize, CHART_TARGET_IS_PNG, font_size);
806 if (PieChart == true)
807 DoUniquePieChart(hsize, vsize, CHART_TARGET_IS_PNG, font_size);
808 }
809 }
810
OnChartSvg(wxCommandEvent & WXUNUSED (event))811 void StatsChartDialog::OnChartSvg(wxCommandEvent & WXUNUSED(event))
812 {
813 // exporting the current Chart as SVG
814 int hsize;
815 int vsize;
816 int font_size;
817 if (ChartData.IsValid() != true)
818 return;
819 switch (SizeCtrl->GetSelection())
820 {
821 case 0:
822 hsize = 256;
823 vsize = 256;
824 font_size = 8;
825 break;
826 case 1:
827 hsize = 512;
828 vsize = 512;
829 font_size = 8;
830 break;
831 case 2:
832 hsize = 1024;
833 vsize = 1024;
834 font_size = 10;
835 break;
836 case 3:
837 hsize = 2048;
838 vsize = 2048;
839 font_size = 12;
840 break;
841 case 4:
842 hsize = 4196;
843 vsize = 4196;
844 font_size = 12;
845 break;
846 };
847
848 // asking an export path
849 int ret;
850 wxString lastDir;
851 wxString fileList = wxT("SVG Vector Image (*.svg)|*.svg");
852 wxFileDialog fileDialog(MainFrame, wxT("saving the current Chart as SVG"),
853 wxT(""), wxT("ChartExport"), fileList,
854 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
855 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
856 lastDir = MainFrame->GetLastDirectory();
857 if (lastDir.Len() >= 1)
858 fileDialog.SetDirectory(lastDir);
859 ret = fileDialog.ShowModal();
860 if (ret == wxID_OK)
861 {
862 wxFileName file(fileDialog.GetPath());
863 lastDir = file.GetPath();
864 MainFrame->SetLastDirectory(lastDir);
865 wxString path = file.GetPath();
866 path += file.GetPathSeparator();
867 path += file.GetName();
868 path += wxT(".svg");
869 ExportPath = path;
870 } else
871 return;
872
873
874 // exporting the Chart as SVG
875 if (ByInterval == true)
876 {
877 if (Histogram == true)
878 DoIntervalHistogram(hsize, vsize, CHART_TARGET_IS_SVG, font_size);
879 if (LineChart == true)
880 DoIntervalLineChart(hsize, vsize, CHART_TARGET_IS_SVG, font_size);
881 if (PieChart == true)
882 DoIntervalPieChart(hsize, vsize, CHART_TARGET_IS_SVG, font_size);
883 } else
884 {
885 if (Histogram == true)
886 DoUniqueHistogram(hsize, vsize, CHART_TARGET_IS_SVG, font_size);
887 if (LineChart == true)
888 DoUniqueLineChart(hsize, vsize, CHART_TARGET_IS_SVG, font_size);
889 if (PieChart == true)
890 DoUniquePieChart(hsize, vsize, CHART_TARGET_IS_SVG, font_size);
891 };
892 }
893
OnChartPdf(wxCommandEvent & WXUNUSED (event))894 void StatsChartDialog::OnChartPdf(wxCommandEvent & WXUNUSED(event))
895 {
896 // exporting the current Chart as PDF
897 int hsize = (int) (12.8 * 300.0);
898 int vsize = (int) (9.0 * 300.0);
899 hsize -= 100; // margin
900 vsize -= 100; // margin
901 if (ChartData.IsValid() != true)
902 return;
903
904 // asking an export path
905 int ret;
906 wxString lastDir;
907 wxString fileList = wxT("PDF Document (*.pdf)|*.pdf");
908 wxFileDialog fileDialog(MainFrame, wxT("saving the current Chart as PDF"),
909 wxT(""), wxT("ChartExport"), fileList,
910 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
911 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
912 lastDir = MainFrame->GetLastDirectory();
913 if (lastDir.Len() >= 1)
914 fileDialog.SetDirectory(lastDir);
915 ret = fileDialog.ShowModal();
916 if (ret == wxID_OK)
917 {
918 wxFileName file(fileDialog.GetPath());
919 lastDir = file.GetPath();
920 MainFrame->SetLastDirectory(lastDir);
921 wxString path = file.GetPath();
922 path += file.GetPathSeparator();
923 path += file.GetName();
924 path += wxT(".pdf");
925 ExportPath = path;
926 } else
927 return;
928
929
930 // exporting the Chart as PDF
931 if (ByInterval == true)
932 {
933 if (Histogram == true)
934 DoIntervalHistogram(hsize, vsize, CHART_TARGET_IS_PDF, 120);
935 if (LineChart == true)
936 DoIntervalLineChart(hsize, vsize, CHART_TARGET_IS_PDF, 120);
937 if (PieChart == true)
938 DoIntervalPieChart(hsize, vsize, CHART_TARGET_IS_PDF, 120);
939 } else
940 {
941 if (Histogram == true)
942 DoUniqueHistogram(hsize, vsize, CHART_TARGET_IS_PDF, 120);
943 if (LineChart == true)
944 DoUniqueLineChart(hsize, vsize, CHART_TARGET_IS_PDF, 120);
945 if (PieChart == true)
946 DoUniquePieChart(hsize, vsize, CHART_TARGET_IS_PDF, 120);
947 };
948 }
949
PrepareDataByInterval(int classes)950 void StatsChartDialog::PrepareDataByInterval(int classes)
951 {
952 // feeding class data by intervals
953 char sql[4196];
954 char table[1024];
955 char column[1024];
956 int ret;
957 char err_msg[2048];
958 sqlite3_stmt *stmt;
959 sqlite3 *sqlite = MainFrame->GetSqlite();
960
961 ChartData.Create(Min, Max, classes);
962
963 strcpy(table, Table.ToUTF8());
964 strcpy(column, Column.ToUTF8());
965 MainFrame->DoubleQuotedSql(table);
966 MainFrame->DoubleQuotedSql(column);
967 sprintf(sql, "SELECT %s FROM %s", column, table);
968 ret = sqlite3_prepare_v2(sqlite, sql, strlen(sql), &stmt, NULL);
969 if (ret != SQLITE_OK)
970 {
971 sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
972 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
973 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
974 return;
975 }
976 while (1)
977 {
978 //
979 // fetching the result set rows
980 //
981 ret = sqlite3_step(stmt);
982 if (ret == SQLITE_DONE)
983 break; // end of result set
984 if (ret == SQLITE_ROW)
985 {
986 //
987 // fetching a row
988 //
989 double value;
990 if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
991 {
992 sqlite3_int64 intval = sqlite3_column_int64(stmt, 0);
993 value = intval;
994 ChartData.Add(value);
995 }
996 if (sqlite3_column_type(stmt, 0) == SQLITE_FLOAT)
997 {
998 value = sqlite3_column_double(stmt, 0);
999 ChartData.Add(value);
1000 }
1001 } else
1002 {
1003 sqlite3_finalize(stmt);
1004 sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
1005 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1006 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1007 return;
1008 }
1009 }
1010 sqlite3_finalize(stmt);
1011 ChartData.SetValid();
1012 }
1013
PrepareDataByUniqueValue(int classes)1014 void StatsChartDialog::PrepareDataByUniqueValue(int classes)
1015 {
1016 // feeding class data by unique values
1017 char sql[4196];
1018 char table[1024];
1019 char column[1024];
1020 int ret;
1021 char err_msg[2048];
1022 sqlite3_stmt *stmt;
1023 sqlite3 *sqlite = MainFrame->GetSqlite();
1024 ChartData.Create(classes);
1025
1026 strcpy(table, Table.ToUTF8());
1027 strcpy(column, Column.ToUTF8());
1028 MainFrame->DoubleQuotedSql(table);
1029 MainFrame->DoubleQuotedSql(column);
1030 sprintf(sql, "SELECT %s, Count(*) FROM %s GROUP BY %s", column, table,
1031 column);
1032 strcat(sql, " ORDER BY 2 DESC");
1033 ret = sqlite3_prepare_v2(sqlite, sql, strlen(sql), &stmt, NULL);
1034 if (ret != SQLITE_OK)
1035 {
1036 sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
1037 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1038 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1039 return;
1040 }
1041 while (1)
1042 {
1043 //
1044 // fetching the result set rows
1045 //
1046 ret = sqlite3_step(stmt);
1047 if (ret == SQLITE_DONE)
1048 break; // end of result set
1049 if (ret == SQLITE_ROW)
1050 {
1051 //
1052 // fetching a row
1053 //
1054 bool valid = false;
1055 wxString value;
1056 char dummy[128];
1057 if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER)
1058 {
1059 sqlite3_int64 intval = sqlite3_column_int64(stmt, 0);
1060 sprintf(dummy, FORMAT_64, intval);
1061 value = wxString::FromUTF8(dummy);
1062 valid = true;
1063 }
1064 if (sqlite3_column_type(stmt, 0) == SQLITE_FLOAT)
1065 {
1066 double dblval = sqlite3_column_double(stmt, 0);
1067 sprintf(dummy, "%1.18f", dblval);
1068 CleanDecimals(dummy);
1069 value = wxString::FromUTF8(dummy);
1070 valid = true;
1071 }
1072 if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1073 {
1074 const char *txtval = (const char *) sqlite3_column_text(stmt, 0);
1075 value = wxString::FromUTF8(txtval);
1076 valid = true;
1077 }
1078 if (valid == true)
1079 {
1080 int count = sqlite3_column_int(stmt, 1);
1081 ChartData.Add(value, count);
1082 }
1083
1084 } else
1085 {
1086 sqlite3_finalize(stmt);
1087 sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
1088 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1089 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1090 return;
1091 }
1092 }
1093 sqlite3_finalize(stmt);
1094 ChartData.SetValid();
1095 }
1096
DoIntervalHistogram(int hsize,int vsize,int target,int font_size)1097 void StatsChartDialog::DoIntervalHistogram(int hsize, int vsize, int target,
1098 int font_size)
1099 {
1100 // generating an Histogram (Interval values)
1101 unsigned char *rgb_array = NULL;
1102 const void *gr = NULL;
1103 const void *font = NULL;
1104 const void *font_big = NULL;
1105 int idx;
1106 int start_x;
1107 int end_x;
1108 int start_y;
1109 int end_y;
1110 double base_x;
1111 double step_x;
1112 double base_y;
1113 double vspan;
1114 double height;
1115 char title[1024];
1116 char text[1024];
1117 char table[1024];
1118 char column[1024];
1119 double txtWidth;
1120 double txtHeight;
1121 double titleHeight;
1122 double pre_x;
1123 double pre_y;
1124 double post_x;
1125 double post_y;
1126 int title_x;
1127 int title_y;
1128 double labelWidth = 0.0;
1129 double labelBase;
1130 double labelStep;
1131 wxColour colors[8];
1132 int color_idx;
1133 MyChartScaleLabels scaleLabels;
1134 MyChartScaleLabel *pLab;
1135 double scaleWidth = 0.0;
1136
1137 // color palette
1138 colors[0] = wxColour(255, 255, 240);
1139 colors[1] = wxColour(255, 240, 255);
1140 colors[2] = wxColour(240, 255, 255);
1141 colors[3] = wxColour(240, 240, 240);
1142 colors[4] = wxColour(255, 192, 192);
1143 colors[5] = wxColour(192, 255, 192);
1144 colors[6] = wxColour(192, 192, 255);
1145 colors[7] = wxColour(192, 192, 192);
1146
1147 // graphics initialization
1148 if (target == CHART_TARGET_IS_SVG)
1149 {
1150 char xpath[2024];
1151 strcpy(xpath, ExportPath.ToUTF8());
1152 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
1153 } else if (target == CHART_TARGET_IS_PDF)
1154 {
1155 char xpath[2024];
1156 strcpy(xpath, ExportPath.ToUTF8());
1157 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
1158 &gr);
1159 } else
1160 gGraphCreateContext(hsize, vsize, &gr);
1161
1162 // background initialization
1163 gGraphSetBrush(gr, 255, 255, 255, 255);
1164 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
1165
1166 // font setup
1167 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
1168 &font);
1169 gGraphFontSetColor(font, 0, 0, 0, 255);
1170 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
1171 &font_big);
1172 gGraphFontSetColor(font_big, 0, 0, 0, 255);
1173
1174 // computing TEXT sizes
1175 strcpy(table, Table.ToUTF8());
1176 strcpy(column, Column.ToUTF8());
1177 MainFrame->DoubleQuotedSql(table);
1178 MainFrame->DoubleQuotedSql(column);
1179 sprintf(title, "Dataset: %s.%s [interval values]", table, column);
1180 gGraphSetFont(gr, font_big);
1181 gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
1182 &post_x, &post_y);
1183 title_x = (hsize - (int) txtWidth) / 2;
1184 title_y = 5 + (int) titleHeight;
1185 // measuring class labels
1186 gGraphSetFont(gr, font);
1187 sprintf(text, "%1.4f", Min);
1188 CleanDecimals(text);
1189 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1190 &post_y);
1191 labelWidth = txtWidth;
1192 sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
1193 CleanDecimals(text);
1194 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1195 &post_y);
1196 if (txtWidth > labelWidth)
1197 labelWidth = txtWidth;
1198 sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
1199 CleanDecimals(text);
1200 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1201 &post_y);
1202 if (txtWidth > labelWidth)
1203 labelWidth = txtWidth;
1204 sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
1205 CleanDecimals(text);
1206 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1207 &post_y);
1208 if (txtWidth > labelWidth)
1209 labelWidth = txtWidth;
1210 sprintf(text, "%1.4f", Max);
1211 CleanDecimals(text);
1212 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1213 &post_y);
1214 if (txtWidth > labelWidth)
1215 labelWidth = txtWidth;
1216
1217 start_y = vsize - 10 - (int) labelWidth;
1218 end_y = 10 + (int) titleHeight;
1219 vspan = start_y - end_y;
1220 base_y = start_y;
1221
1222 // building and measuring the 'scale' labels
1223 scaleLabels.Initialize(vspan, ChartData.GetMaxFreq());
1224 pLab = scaleLabels.GetFirst();
1225 while (pLab)
1226 {
1227 gGraphSetFont(gr, font);
1228 strcpy(text, pLab->GetLabel().ToUTF8());
1229 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1230 &post_x, &post_y);
1231 if (txtWidth > scaleWidth)
1232 scaleWidth = txtWidth;
1233 pLab = pLab->GetNext();
1234 }
1235
1236 start_x = 10 + (int) scaleWidth;
1237 end_x = hsize - 10;
1238 base_x = start_x;
1239 step_x = (double) (end_x - start_x) / (double) (ChartData.GetNumClasses());
1240 labelBase = base_x + (step_x / 2.0);
1241 labelStep = (end_x - start_x - step_x) / 4;
1242
1243 // title output
1244 gGraphSetFont(gr, font_big);
1245 gGraphDrawText(gr, title, title_x, title_y, 0.0);
1246 // class labels output
1247 gGraphSetFont(gr, font);
1248 sprintf(text, "%1.4f", Min);
1249 CleanDecimals(text);
1250 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1251 &post_y);
1252 gGraphDrawText(gr, text, labelBase + txtHeight,
1253 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1254 labelBase += labelStep;
1255 sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
1256 CleanDecimals(text);
1257 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1258 &post_y);
1259 gGraphDrawText(gr, text, labelBase + txtHeight,
1260 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1261 labelBase += labelStep;
1262 sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
1263 CleanDecimals(text);
1264 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1265 &post_y);
1266 gGraphDrawText(gr, text, labelBase + txtHeight,
1267 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1268 labelBase += labelStep;
1269 sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
1270 CleanDecimals(text);
1271 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1272 &post_y);
1273 gGraphDrawText(gr, text, labelBase + txtHeight,
1274 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1275 labelBase += labelStep;
1276 sprintf(text, "%1.4f", Max);
1277 CleanDecimals(text);
1278 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1279 &post_y);
1280 gGraphDrawText(gr, text, labelBase + txtHeight,
1281 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1282
1283 for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
1284 {
1285 // drawing bars
1286 MyChartIntervalClass *p = ChartData.GetClass(idx);
1287 gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
1288 color_idx = idx % 8;
1289 gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
1290 colors[color_idx].Blue(), 255);
1291 height =
1292 vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
1293 gGraphDrawRectangle(gr, base_x, base_y - height, step_x, height);
1294 base_x += step_x;
1295 }
1296 // drawing 'scale' labels
1297 pLab = scaleLabels.GetFirst();
1298 while (pLab)
1299 {
1300 gGraphSetFont(gr, font);
1301 strcpy(text, pLab->GetLabel().ToUTF8());
1302 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1303 &post_x, &post_y);
1304 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
1305 base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
1306 gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
1307 gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
1308 base_y - pLab->GetPosition());
1309 pLab = pLab->GetNext();
1310 }
1311 // marking the ZERO baseline
1312 gGraphSetFont(gr, font);
1313 strcpy(text, "0");
1314 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1315 &post_y);
1316 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
1317 base_y + (txtHeight / 2.0), 0.0);
1318 gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
1319 gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
1320
1321 // graphics finalization
1322 gGraphDestroyFont(font);
1323 gGraphDestroyFont(font_big);
1324 if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
1325 || target == CHART_TARGET_IS_PREVIEW)
1326 gGraphGetContextRgbArray(gr, &rgb_array);
1327 if (target == CHART_TARGET_IS_SVG)
1328 gGraphDestroySvgContext(gr);
1329 else if (target == CHART_TARGET_IS_PDF)
1330 gGraphDestroyPdfContext(gr);
1331 else
1332 gGraphDestroyContext(gr);
1333
1334 if (target == CHART_TARGET_IS_PNG)
1335 {
1336 if (rgb_array)
1337 {
1338 // creating the Image from RGB array
1339 const void *img =
1340 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
1341 if (img)
1342 {
1343 char xpath[2024];
1344 strcpy(xpath, ExportPath.ToUTF8());
1345 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
1346 {
1347 wxString msg =
1348 wxT
1349 ("An error occurred while saving\nthe current Char as PNG");
1350 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1351 MainFrame);
1352 }
1353 gGraphDestroyImage(img);
1354 }
1355 }
1356 }
1357 if (target == CHART_TARGET_IS_PREVIEW)
1358 {
1359 if (rgb_array)
1360 {
1361 // creating the Image from RGB array
1362 wxImage img(hsize, vsize);
1363 img.SetData(rgb_array);
1364 wxBitmap bmp(img);
1365 ChartShow->SetBitmap(bmp);
1366 }
1367 }
1368 if (target == CHART_TARGET_IS_COPY)
1369 {
1370 if (rgb_array)
1371 {
1372 // creating the Image from RGB array
1373 wxImage img(hsize, vsize);
1374 img.SetData(rgb_array);
1375 if (wxTheClipboard->Open())
1376 {
1377 wxTheClipboard->SetData(new wxBitmapDataObject(img));
1378 wxTheClipboard->Close();
1379 }
1380 }
1381 }
1382 }
1383
DoIntervalLineChart(int hsize,int vsize,int target,int font_size)1384 void StatsChartDialog::DoIntervalLineChart(int hsize, int vsize, int target,
1385 int font_size)
1386 {
1387 // generating a Line Chart (Interval values)
1388 unsigned char *rgb_array = NULL;
1389 const void *gr = NULL;
1390 const void *font = NULL;
1391 const void *font_big = NULL;
1392 int idx;
1393 int start_x;
1394 int end_x;
1395 int start_y;
1396 int end_y;
1397 double base_x;
1398 double step_x;
1399 double base_y;
1400 double vspan;
1401 double height;
1402 char title[1024];
1403 char table[1024];
1404 char column[1024];
1405 char text[1024];
1406 double txtWidth;
1407 double txtHeight;
1408 double titleHeight;
1409 double pre_x;
1410 double pre_y;
1411 double post_x;
1412 double post_y;
1413 int title_x;
1414 int title_y;
1415 double labelWidth = 0.0;
1416 double labelBase;
1417 double labelStep;
1418 MyChartScaleLabels scaleLabels;
1419 MyChartScaleLabel *pLab;
1420 double scaleWidth = 0.0;
1421
1422 // graphics initialization
1423 if (target == CHART_TARGET_IS_SVG)
1424 {
1425 char xpath[2024];
1426 strcpy(xpath, ExportPath.ToUTF8());
1427 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
1428 } else if (target == CHART_TARGET_IS_PDF)
1429 {
1430 char xpath[2024];
1431 strcpy(xpath, ExportPath.ToUTF8());
1432 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
1433 &gr);
1434 } else
1435 gGraphCreateContext(hsize, vsize, &gr);
1436
1437 // background initialization
1438 gGraphSetBrush(gr, 255, 255, 255, 255);
1439 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
1440
1441 // font setup
1442 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
1443 &font);
1444 gGraphFontSetColor(font, 0, 0, 0, 255);
1445 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
1446 &font_big);
1447 gGraphFontSetColor(font_big, 0, 0, 0, 255);
1448
1449 // computing TEXT sizes
1450 strcpy(table, Table.ToUTF8());
1451 strcpy(column, Column.ToUTF8());
1452 MainFrame->DoubleQuotedSql(table);
1453 MainFrame->DoubleQuotedSql(column);
1454 sprintf(title, "Dataset: %s.%s [interval values]", table, column);
1455 gGraphSetFont(gr, font_big);
1456 gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
1457 &post_x, &post_y);
1458 title_x = (hsize - (int) txtWidth) / 2;
1459 title_y = 5 + (int) titleHeight;
1460 // measuring class labels
1461 gGraphSetFont(gr, font);
1462 sprintf(text, "%1.4f", Min);
1463 CleanDecimals(text);
1464 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1465 &post_y);
1466 labelWidth = txtWidth;
1467 sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
1468 CleanDecimals(text);
1469 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1470 &post_y);
1471 if (txtWidth > labelWidth)
1472 labelWidth = txtWidth;
1473 sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
1474 CleanDecimals(text);
1475 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1476 &post_y);
1477 if (txtWidth > labelWidth)
1478 labelWidth = txtWidth;
1479 sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
1480 CleanDecimals(text);
1481 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1482 &post_y);
1483 if (txtWidth > labelWidth)
1484 labelWidth = txtWidth;
1485 sprintf(text, "%1.4f", Max);
1486 CleanDecimals(text);
1487 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1488 &post_y);
1489 if (txtWidth > labelWidth)
1490 labelWidth = txtWidth;
1491
1492 start_y = vsize - 10 - (int) labelWidth;
1493 end_y = 10 + (int) titleHeight;
1494 vspan = start_y - end_y;
1495 base_y = start_y;
1496
1497 // building and measuring the 'scale' labels
1498 scaleLabels.Initialize(vspan, ChartData.GetMaxFreq());
1499 pLab = scaleLabels.GetFirst();
1500 while (pLab)
1501 {
1502 gGraphSetFont(gr, font);
1503 strcpy(text, pLab->GetLabel().ToUTF8());
1504 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1505 &post_x, &post_y);
1506 if (txtWidth > scaleWidth)
1507 scaleWidth = txtWidth;
1508 pLab = pLab->GetNext();
1509 }
1510
1511 start_x = 10 + (int) scaleWidth;
1512 end_x = hsize - 10;
1513 base_x = start_x;
1514 step_x = (double) (end_x - start_x) / (double) (ChartData.GetNumClasses());
1515 labelBase = base_x + (step_x / 2.0);
1516 labelStep = (end_x - start_x - step_x) / 4;
1517
1518 // title output
1519 gGraphSetFont(gr, font_big);
1520 gGraphDrawText(gr, title, title_x, title_y, 0.0);
1521 // class labels output
1522 gGraphSetFont(gr, font);
1523 sprintf(text, "%1.4f", Min);
1524 CleanDecimals(text);
1525 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1526 &post_y);
1527 gGraphDrawText(gr, text, labelBase + txtHeight,
1528 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1529 labelBase += labelStep;
1530 sprintf(text, "%1.4f", Min + ((Max - Min) / 4.0));
1531 CleanDecimals(text);
1532 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1533 &post_y);
1534 gGraphDrawText(gr, text, labelBase + txtHeight,
1535 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1536 labelBase += labelStep;
1537 sprintf(text, "%1.4f", Min + ((Max - Min) / 2.0));
1538 CleanDecimals(text);
1539 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1540 &post_y);
1541 gGraphDrawText(gr, text, labelBase + txtHeight,
1542 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1543 labelBase += labelStep;
1544 sprintf(text, "%1.4f", Min + (((Max - Min) / 4.0) * 3.0));
1545 CleanDecimals(text);
1546 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1547 &post_y);
1548 gGraphDrawText(gr, text, labelBase + txtHeight,
1549 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1550 labelBase += labelStep;
1551 sprintf(text, "%1.4f", Max);
1552 CleanDecimals(text);
1553 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1554 &post_y);
1555 gGraphDrawText(gr, text, labelBase + txtHeight,
1556 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
1557
1558 for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
1559 {
1560 MyChartIntervalClass *p = ChartData.GetClass(idx);
1561 height =
1562 vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
1563 gGraphSetPen(gr, 192, 192, 192, 255, 1, GGRAPH_PENSTYLE_DOT);
1564 gGraphStrokeLine(gr, base_x + (step_x / 2.0), start_y,
1565 base_x + (step_x / 2.0), base_y - height);
1566 base_x += step_x;
1567 }
1568 base_x = start_x;
1569 for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
1570 {
1571 MyChartIntervalClass *p = ChartData.GetClass(idx);
1572 height =
1573 vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
1574 if (idx == 0)
1575 gGraphMoveToPoint(gr, base_x + (step_x / 2.0), base_y - height);
1576 else
1577 gGraphAddLineToPath(gr, base_x + (step_x / 2.0), base_y - height);
1578 base_x += step_x;
1579 }
1580 gGraphSetPen(gr, 255, 0, 0, 255, 2, GGRAPH_PENSTYLE_SOLID);
1581 gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
1582
1583 // drawing 'scale' labels
1584 pLab = scaleLabels.GetFirst();
1585 while (pLab)
1586 {
1587 gGraphSetFont(gr, font);
1588 strcpy(text, pLab->GetLabel().ToUTF8());
1589 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1590 &post_x, &post_y);
1591 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
1592 base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
1593 gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
1594 gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
1595 base_y - pLab->GetPosition());
1596 pLab = pLab->GetNext();
1597 }
1598 // marking the ZERO baseline
1599 gGraphSetFont(gr, font);
1600 strcpy(text, "0");
1601 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
1602 &post_y);
1603 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
1604 base_y + (txtHeight / 2.0), 0.0);
1605 gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
1606 gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
1607
1608 // graphics finalization
1609 gGraphDestroyFont(font);
1610 gGraphDestroyFont(font_big);
1611 if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
1612 || target == CHART_TARGET_IS_PREVIEW)
1613 gGraphGetContextRgbArray(gr, &rgb_array);
1614 if (target == CHART_TARGET_IS_SVG)
1615 gGraphDestroySvgContext(gr);
1616 else if (target == CHART_TARGET_IS_PDF)
1617 gGraphDestroyPdfContext(gr);
1618 else
1619 gGraphDestroyContext(gr);
1620
1621 if (target == CHART_TARGET_IS_PNG)
1622 {
1623 if (rgb_array)
1624 {
1625 // creating the Image from RGB array
1626 const void *img =
1627 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
1628 if (img)
1629 {
1630 char xpath[2024];
1631 strcpy(xpath, ExportPath.ToUTF8());
1632 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
1633 {
1634 wxString msg =
1635 wxT
1636 ("An error occurred while saving\nthe current Char as PNG");
1637 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1638 MainFrame);
1639 }
1640 gGraphDestroyImage(img);
1641 }
1642 }
1643 }
1644 if (target == CHART_TARGET_IS_PREVIEW)
1645 {
1646 if (rgb_array)
1647 {
1648 // creating the Image from RGB array
1649 wxImage img(hsize, vsize);
1650 img.SetData(rgb_array);
1651 wxBitmap bmp(img);
1652 ChartShow->SetBitmap(bmp);
1653 }
1654 }
1655 if (target == CHART_TARGET_IS_COPY)
1656 {
1657 if (rgb_array)
1658 {
1659 // creating the Image from RGB array
1660 wxImage img(hsize, vsize);
1661 img.SetData(rgb_array);
1662 if (wxTheClipboard->Open())
1663 {
1664 wxTheClipboard->SetData(new wxBitmapDataObject(img));
1665 wxTheClipboard->Close();
1666 }
1667 }
1668 }
1669 }
1670
DoIntervalPieChart(int hsize,int vsize,int target,int font_size)1671 void StatsChartDialog::DoIntervalPieChart(int hsize, int vsize, int target,
1672 int font_size)
1673 {
1674 // generating a Pie Chart (Interval values)
1675 unsigned char *rgb_array = NULL;
1676 const void *gr = NULL;
1677 const void *font = NULL;
1678 const void *font_big = NULL;
1679 int idx;
1680 double radius_x;
1681 double radius_y;
1682 double radius;
1683 double cx;
1684 double cy;
1685 double from;
1686 double step;
1687 char title[1024];
1688 char table[1024];
1689 char column[1024];
1690 double txtWidth;
1691 double txtHeight;
1692 double titleHeight;
1693 double pre_x;
1694 double pre_y;
1695 double post_x;
1696 double post_y;
1697 int title_x;
1698 int title_y;
1699 wxColour colors[8];
1700 int color_idx;
1701 MyPieChartLabels labels;
1702 MyPieChartLabel *pLab;
1703 char text[1024];
1704 double lx;
1705 double ly;
1706 double base_y;
1707 double step_y;
1708 double labelWidth = 0.0;
1709
1710 // color palette
1711 colors[0] = wxColour(255, 255, 240);
1712 colors[1] = wxColour(255, 240, 255);
1713 colors[2] = wxColour(240, 255, 255);
1714 colors[3] = wxColour(240, 240, 240);
1715 colors[4] = wxColour(255, 192, 192);
1716 colors[5] = wxColour(192, 255, 192);
1717 colors[6] = wxColour(192, 192, 255);
1718 colors[7] = wxColour(192, 192, 192);
1719
1720 // graphics initialization
1721 if (target == CHART_TARGET_IS_SVG)
1722 {
1723 char xpath[2024];
1724 strcpy(xpath, ExportPath.ToUTF8());
1725 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
1726 } else if (target == CHART_TARGET_IS_PDF)
1727 {
1728 char xpath[2024];
1729 strcpy(xpath, ExportPath.ToUTF8());
1730 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
1731 &gr);
1732 } else
1733 gGraphCreateContext(hsize, vsize, &gr);
1734
1735 // background initialization
1736 gGraphSetBrush(gr, 255, 255, 255, 255);
1737 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
1738
1739 // font setup
1740 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
1741 &font);
1742 gGraphFontSetColor(font, 0, 0, 0, 255);
1743 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
1744 &font_big);
1745 gGraphFontSetColor(font_big, 0, 0, 0, 255);
1746
1747 // computing TEXT sizes
1748 strcpy(table, Table.ToUTF8());
1749 strcpy(column, Column.ToUTF8());
1750 MainFrame->DoubleQuotedSql(table);
1751 MainFrame->DoubleQuotedSql(column);
1752 sprintf(title, "Dataset: %s.%s [interval values]", table, column);
1753 gGraphSetFont(gr, font_big);
1754 gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
1755 &post_x, &post_y);
1756 title_x = (hsize - (int) txtWidth) / 2;
1757 title_y = 5 + (int) titleHeight;
1758 for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
1759 {
1760 // measuring labels
1761 MyChartIntervalClass *p = ChartData.GetClass(idx);
1762 gGraphSetFont(gr, font);
1763 sprintf(text, "%1.4f", p->GetMin() + ((p->GetMax() - p->GetMin()) / 2.0));
1764 CleanDecimals(text);
1765 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1766 &post_x, &post_y);
1767 if (txtWidth > labelWidth)
1768 labelWidth = txtWidth;
1769 }
1770
1771 cx = (double) hsize / 2.0;
1772 cy = (double) vsize / 2.0;
1773 cy += (double) (titleHeight + 10) / 2.0;
1774 radius_x = (double) (hsize - 20) / 2.0;
1775 radius_x -= labelWidth + 10;
1776 radius_y = (double) (vsize - titleHeight - 20) / 2.0;
1777 if (radius_x <= radius_y)
1778 radius = radius_x;
1779 else
1780 radius = radius_y;
1781
1782 // title output
1783 gGraphSetFont(gr, font_big);
1784 gGraphDrawText(gr, title, title_x, title_y, 0.0);
1785
1786 from = 0.0;
1787 for (idx = 0; idx < ChartData.GetNumClasses(); idx++)
1788 {
1789 MyChartIntervalClass *p = ChartData.GetClass(idx);
1790 gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
1791 color_idx = idx % 8;
1792 gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
1793 colors[color_idx].Blue(), 255);
1794 step =
1795 (M_PI * 2.0) *
1796 ((double) (p->GetCount() / (double) (ChartData.GetTotFreq())));
1797 gGraphDrawCircleSector(gr, cx, cy, radius, from, from + step);
1798 sprintf(text, "%1.4f", p->GetMin() + ((p->GetMax() - p->GetMin()) / 2.0));
1799 CleanDecimals(text);
1800 lx = cx + (radius * 0.90) * cos(from + (step / 2.0));
1801 ly = cy + (radius * 0.90) * sin(from + (step / 2.0));
1802 labels.Add(text, lx, ly);
1803 from += step;
1804 }
1805 // printing class labels
1806 labels.Sort(cx);
1807 step_y = (double) (vsize - 50) / (double) (labels.GetNumLeftLabels() - 1);
1808 base_y = 25.0;
1809 for (idx = 0; idx < labels.GetNumLeftLabels(); idx++)
1810 {
1811 // printing Left labels
1812 pLab = labels.GetLeftLabel(idx);
1813 strcpy(text, pLab->GetLabel().ToUTF8());
1814 gGraphSetFont(gr, font);
1815 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1816 &post_x, &post_y);
1817 gGraphDrawText(gr, text, 10, base_y + (txtHeight / 2.0), 0.0);
1818 gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
1819 gGraphStrokeLine(gr, 10 + txtWidth, base_y, pLab->GetX(), pLab->GetY());
1820 base_y += step_y;
1821 }
1822 step_y = (double) (vsize - 50) / (double) (labels.GetNumRightLabels() - 1);
1823 base_y = 25.0;
1824 for (idx = 0; idx < labels.GetNumRightLabels(); idx++)
1825 {
1826 // printing Right labels
1827 pLab = labels.GetRightLabel(idx);
1828 strcpy(text, pLab->GetLabel().ToUTF8());
1829 gGraphSetFont(gr, font);
1830 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
1831 &post_x, &post_y);
1832 gGraphDrawText(gr, text, hsize - txtWidth - 10,
1833 base_y + (txtHeight / 2.0), 0.0);
1834 gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
1835 gGraphStrokeLine(gr, hsize - txtWidth - 10, base_y, pLab->GetX(),
1836 pLab->GetY());
1837 base_y += step_y;
1838 }
1839
1840 // graphics finalization
1841 gGraphDestroyFont(font);
1842 gGraphDestroyFont(font_big);
1843 if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
1844 || target == CHART_TARGET_IS_PREVIEW)
1845 gGraphGetContextRgbArray(gr, &rgb_array);
1846 if (target == CHART_TARGET_IS_SVG)
1847 gGraphDestroySvgContext(gr);
1848 else if (target == CHART_TARGET_IS_PDF)
1849 gGraphDestroyPdfContext(gr);
1850 else
1851 gGraphDestroyContext(gr);
1852
1853 if (target == CHART_TARGET_IS_PNG)
1854 {
1855 if (rgb_array)
1856 {
1857 // creating the Image from RGB array
1858 const void *img =
1859 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
1860 if (img)
1861 {
1862 char xpath[2024];
1863 strcpy(xpath, ExportPath.ToUTF8());
1864 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
1865 {
1866 wxString msg =
1867 wxT
1868 ("An error occurred while saving\nthe current Char as PNG");
1869 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1870 MainFrame);
1871 }
1872 gGraphDestroyImage(img);
1873 }
1874 }
1875 }
1876 if (target == CHART_TARGET_IS_PREVIEW)
1877 {
1878 if (rgb_array)
1879 {
1880 // creating the Image from RGB array
1881 wxImage img(hsize, vsize);
1882 img.SetData(rgb_array);
1883 wxBitmap bmp(img);
1884 ChartShow->SetBitmap(bmp);
1885 }
1886 }
1887 if (target == CHART_TARGET_IS_COPY)
1888 {
1889 if (rgb_array)
1890 {
1891 // creating the Image from RGB array
1892 wxImage img(hsize, vsize);
1893 img.SetData(rgb_array);
1894 if (wxTheClipboard->Open())
1895 {
1896 wxTheClipboard->SetData(new wxBitmapDataObject(img));
1897 wxTheClipboard->Close();
1898 }
1899 }
1900 }
1901 }
1902
DoUniqueHistogram(int hsize,int vsize,int target,int font_size)1903 void StatsChartDialog::DoUniqueHistogram(int hsize, int vsize, int target,
1904 int font_size)
1905 {
1906 // generating an Histogram (Unique values)
1907 unsigned char *rgb_array = NULL;
1908 const void *gr = NULL;
1909 const void *font = NULL;
1910 const void *font_big = NULL;
1911 int idx;
1912 MyChartUniqueClass *p;
1913 int start_x;
1914 int end_x;
1915 int start_y;
1916 int end_y;
1917 double base_x;
1918 double step_x;
1919 double base_y;
1920 double vspan;
1921 double height;
1922 char title[1024];
1923 char table[1024];
1924 char column[1024];
1925 char text[1024];
1926 double txtWidth;
1927 double txtHeight;
1928 double titleHeight;
1929 double pre_x;
1930 double pre_y;
1931 double post_x;
1932 double post_y;
1933 int title_x;
1934 int title_y;
1935 double labelWidth = 0.0;
1936 int others = 0;
1937 wxColour colors[8];
1938 int color_idx;
1939 MyChartScaleLabels scaleLabels;
1940 MyChartScaleLabel *pLab;
1941 double scaleWidth = 0.0;
1942
1943 // color palette
1944 colors[0] = wxColour(255, 255, 240);
1945 colors[1] = wxColour(255, 240, 255);
1946 colors[2] = wxColour(240, 255, 255);
1947 colors[3] = wxColour(240, 240, 240);
1948 colors[4] = wxColour(255, 192, 192);
1949 colors[5] = wxColour(192, 255, 192);
1950 colors[6] = wxColour(192, 192, 255);
1951 colors[7] = wxColour(192, 192, 192);
1952
1953 // graphics initialization
1954 if (target == CHART_TARGET_IS_SVG)
1955 {
1956 char xpath[2024];
1957 strcpy(xpath, ExportPath.ToUTF8());
1958 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
1959 } else if (target == CHART_TARGET_IS_PDF)
1960 {
1961 char xpath[2024];
1962 strcpy(xpath, ExportPath.ToUTF8());
1963 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
1964 &gr);
1965 } else
1966 gGraphCreateContext(hsize, vsize, &gr);
1967
1968 // background initialization
1969 gGraphSetBrush(gr, 255, 255, 255, 255);
1970 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
1971
1972 // font setup
1973 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
1974 &font);
1975 gGraphFontSetColor(font, 0, 0, 0, 255);
1976 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
1977 &font_big);
1978 gGraphFontSetColor(font_big, 0, 0, 0, 255);
1979
1980 if (ChartData.GetOtherUniquesFreq() > 0)
1981 others = 1;
1982 // computing TEXT sizes
1983 strcpy(table, Table.ToUTF8());
1984 strcpy(column, Column.ToUTF8());
1985 MainFrame->DoubleQuotedSql(table);
1986 MainFrame->DoubleQuotedSql(column);
1987 sprintf(title, "Dataset: %s.%s [unique values]", table, column);
1988 gGraphSetFont(gr, font_big);
1989 gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
1990 &post_x, &post_y);
1991 title_x = (hsize - (int) txtWidth) / 2;
1992 title_y = 5 + (int) titleHeight;
1993 // measuring class labels
1994 p = ChartData.GetFirst();
1995 while (p)
1996 {
1997 gGraphSetFont(gr, font);
1998 strcpy(text, p->GetValue().ToUTF8());
1999 if (strlen(text) > 10)
2000 {
2001 text[10] = '.';
2002 text[11] = '.';
2003 text[12] = '\0'; // truncating to max 10 chars
2004 }
2005 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2006 &post_x, &post_y);
2007 if (txtWidth > labelWidth)
2008 labelWidth = txtWidth;
2009 p = p->GetNext();
2010 }
2011 if (others)
2012 {
2013 // including the 'any other' class
2014 gGraphSetFont(gr, font);
2015 gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
2016 &post_x, &post_y);
2017 if (txtWidth > labelWidth)
2018 labelWidth = txtWidth;
2019 }
2020
2021 start_y = vsize - 10 - (int) labelWidth;
2022 end_y = 10 + (int) titleHeight;
2023 vspan = start_y - end_y;
2024 base_y = start_y;
2025
2026 // building and measuring the 'scale' labels
2027 scaleLabels.Initialize(vspan, ChartData.GetMaxFreq());
2028 pLab = scaleLabels.GetFirst();
2029 while (pLab)
2030 {
2031 gGraphSetFont(gr, font);
2032 strcpy(text, pLab->GetLabel().ToUTF8());
2033 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2034 &post_x, &post_y);
2035 if (txtWidth > scaleWidth)
2036 scaleWidth = txtWidth;
2037 pLab = pLab->GetNext();
2038 }
2039
2040 start_x = 10 + (int) scaleWidth;
2041 end_x = hsize - 10;
2042 base_x = start_x;
2043 step_x =
2044 (double) (end_x - start_x) / (double) (ChartData.GetNumClasses() + others);
2045
2046 // title output
2047 gGraphSetFont(gr, font_big);
2048 gGraphDrawText(gr, title, title_x, title_y, 0.0);
2049 // class labels output
2050 p = ChartData.GetFirst();
2051 while (p)
2052 {
2053 gGraphSetFont(gr, font);
2054 strcpy(text, p->GetValue().ToUTF8());
2055 if (strlen(text) > 10)
2056 {
2057 text[10] = '.';
2058 text[11] = '.';
2059 text[12] = '\0'; // truncating to max 10 chars
2060 }
2061 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2062 &post_x, &post_y);
2063 gGraphDrawText(gr, text, base_x + (txtHeight / 2.0) + (step_x / 2.0),
2064 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
2065 base_x += step_x;
2066 p = p->GetNext();
2067 }
2068 if (others)
2069 {
2070 // including the 'any other' class
2071 gGraphSetFont(gr, font);
2072 gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
2073 &post_x, &post_y);
2074 gGraphDrawText(gr, "AnyOther",
2075 base_x + (txtHeight / 2.0) + (step_x / 2.0),
2076 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
2077 }
2078
2079 idx = 0;
2080 base_x = start_x;
2081 p = ChartData.GetFirst();
2082 while (p)
2083 {
2084 gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
2085 color_idx = idx % 8;
2086 gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
2087 colors[color_idx].Blue(), 255);
2088 height =
2089 vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
2090 gGraphDrawRectangle(gr, base_x, base_y - height, step_x, height);
2091 base_x += step_x;
2092 idx++;
2093 p = p->GetNext();
2094 }
2095 if (others)
2096 {
2097 // other unclassified values
2098 color_idx = idx % 8;
2099 gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
2100 colors[color_idx].Blue(), 255);
2101 height =
2102 vspan *
2103 ((double)
2104 (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetMaxFreq())));
2105 gGraphDrawRectangle(gr, base_x, base_y - height, step_x, height);
2106 }
2107 // drawing 'scale' labels
2108 pLab = scaleLabels.GetFirst();
2109 while (pLab)
2110 {
2111 gGraphSetFont(gr, font);
2112 strcpy(text, pLab->GetLabel().ToUTF8());
2113 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2114 &post_x, &post_y);
2115 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
2116 base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
2117 gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
2118 gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
2119 base_y - pLab->GetPosition());
2120 pLab = pLab->GetNext();
2121 }
2122 // marking the ZERO baseline
2123 gGraphSetFont(gr, font);
2124 strcpy(text, "0");
2125 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
2126 &post_y);
2127 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
2128 base_y + (txtHeight / 2.0), 0.0);
2129 gGraphSetPen(gr, 255, 128, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
2130 gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
2131
2132 // graphics finalization
2133 gGraphDestroyFont(font);
2134 gGraphDestroyFont(font_big);
2135 if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
2136 || target == CHART_TARGET_IS_PREVIEW)
2137 gGraphGetContextRgbArray(gr, &rgb_array);
2138 if (target == CHART_TARGET_IS_SVG)
2139 gGraphDestroySvgContext(gr);
2140 else if (target == CHART_TARGET_IS_PDF)
2141 gGraphDestroyPdfContext(gr);
2142 else
2143 gGraphDestroyContext(gr);
2144
2145 if (target == CHART_TARGET_IS_PNG)
2146 {
2147 if (rgb_array)
2148 {
2149 // creating the Image from RGB array
2150 const void *img =
2151 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
2152 if (img)
2153 {
2154 char xpath[2024];
2155 strcpy(xpath, ExportPath.ToUTF8());
2156 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
2157 {
2158 wxString msg =
2159 wxT
2160 ("An error occurred while saving\nthe current Char as PNG");
2161 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
2162 MainFrame);
2163 }
2164 gGraphDestroyImage(img);
2165 }
2166 }
2167 }
2168 if (target == CHART_TARGET_IS_PREVIEW)
2169 {
2170 if (rgb_array)
2171 {
2172 // creating the Image from RGB array
2173 wxImage img(hsize, vsize);
2174 img.SetData(rgb_array);
2175 wxBitmap bmp(img);
2176 ChartShow->SetBitmap(bmp);
2177 }
2178 }
2179 if (target == CHART_TARGET_IS_COPY)
2180 {
2181 if (rgb_array)
2182 {
2183 // creating the Image from RGB array
2184 wxImage img(hsize, vsize);
2185 img.SetData(rgb_array);
2186 if (wxTheClipboard->Open())
2187 {
2188 wxTheClipboard->SetData(new wxBitmapDataObject(img));
2189 wxTheClipboard->Close();
2190 }
2191 }
2192 }
2193 }
2194
DoUniqueLineChart(int hsize,int vsize,int target,int font_size)2195 void StatsChartDialog::DoUniqueLineChart(int hsize, int vsize, int target,
2196 int font_size)
2197 {
2198 // generating a Line Chart (Unique values)
2199 unsigned char *rgb_array = NULL;
2200 const void *gr = NULL;
2201 const void *font = NULL;
2202 const void *font_big = NULL;
2203 int idx;
2204 MyChartUniqueClass *p;
2205 int start_x;
2206 int end_x;
2207 int start_y;
2208 int end_y;
2209 double base_x;
2210 double step_x;
2211 double base_y;
2212 double vspan;
2213 double height;
2214 char title[1024];
2215 char table[1024];
2216 char column[1024];
2217 char text[1024];
2218 double txtWidth;
2219 double txtHeight;
2220 double titleHeight;
2221 double pre_x;
2222 double pre_y;
2223 double post_x;
2224 double post_y;
2225 int title_x;
2226 int title_y;
2227 double labelWidth = 0.0;
2228 int others = 0;
2229 MyChartScaleLabels scaleLabels;
2230 MyChartScaleLabel *pLab;
2231 double scaleWidth = 0.0;
2232
2233 // graphics initialization
2234 if (target == CHART_TARGET_IS_SVG)
2235 {
2236 char xpath[2024];
2237 strcpy(xpath, ExportPath.ToUTF8());
2238 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
2239 } else if (target == CHART_TARGET_IS_PDF)
2240 {
2241 char xpath[2024];
2242 strcpy(xpath, ExportPath.ToUTF8());
2243 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
2244 &gr);
2245 } else
2246 gGraphCreateContext(hsize, vsize, &gr);
2247
2248 // background initialization
2249 gGraphSetBrush(gr, 255, 255, 255, 255);
2250 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
2251
2252 // font setup
2253 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
2254 &font);
2255 gGraphFontSetColor(font, 0, 0, 0, 255);
2256 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
2257 &font_big);
2258 gGraphFontSetColor(font_big, 0, 0, 0, 255);
2259
2260 if (ChartData.GetOtherUniquesFreq() > 0)
2261 others = 1;
2262 // computing TEXT sizes
2263 strcpy(table, Table.ToUTF8());
2264 strcpy(column, Column.ToUTF8());
2265 MainFrame->DoubleQuotedSql(table);
2266 MainFrame->DoubleQuotedSql(column);
2267 sprintf(title, "Dataset: %s.%s [unique values]", table, column);
2268 gGraphSetFont(gr, font_big);
2269 gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
2270 &post_x, &post_y);
2271 title_x = (hsize - (int) txtWidth) / 2;
2272 title_y = 5 + (int) titleHeight;
2273 // measuring class labels
2274 p = ChartData.GetFirst();
2275 while (p)
2276 {
2277 gGraphSetFont(gr, font);
2278 strcpy(text, p->GetValue().ToUTF8());
2279 if (strlen(text) > 10)
2280 {
2281 text[10] = '.';
2282 text[11] = '.';
2283 text[12] = '\0'; // truncating to max 10 chars
2284 }
2285 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2286 &post_x, &post_y);
2287 if (txtWidth > labelWidth)
2288 labelWidth = txtWidth;
2289 p = p->GetNext();
2290 }
2291 if (others)
2292 {
2293 // including the 'any other' class
2294 gGraphSetFont(gr, font);
2295 gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
2296 &post_x, &post_y);
2297 if (txtWidth > labelWidth)
2298 labelWidth = txtWidth;
2299 }
2300
2301 start_y = vsize - 10 - (int) labelWidth;
2302 end_y = 10 + (int) titleHeight;
2303 vspan = start_y - end_y;
2304 base_y = start_y;
2305
2306 // building and measuring the 'scale' labels
2307 scaleLabels.Initialize(vspan, ChartData.GetMaxFreq());
2308 pLab = scaleLabels.GetFirst();
2309 while (pLab)
2310 {
2311 gGraphSetFont(gr, font);
2312 strcpy(text, pLab->GetLabel().ToUTF8());
2313 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2314 &post_x, &post_y);
2315 if (txtWidth > scaleWidth)
2316 scaleWidth = txtWidth;
2317 pLab = pLab->GetNext();
2318 }
2319
2320 start_x = 10 + (int) scaleWidth;
2321 end_x = hsize - 10;
2322 base_x = start_x;
2323 step_x =
2324 (double) (end_x - start_x) / (double) (ChartData.GetNumClasses() + others);
2325
2326 // title output
2327 gGraphSetFont(gr, font_big);
2328 gGraphDrawText(gr, title, title_x, title_y, 0.0);
2329 // class labels output
2330 p = ChartData.GetFirst();
2331 while (p)
2332 {
2333 gGraphSetFont(gr, font);
2334 strcpy(text, p->GetValue().ToUTF8());
2335 if (strlen(text) > 10)
2336 {
2337 text[10] = '.';
2338 text[11] = '.';
2339 text[12] = '\0'; // truncating to max 10 chars
2340 }
2341 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2342 &post_x, &post_y);
2343 gGraphDrawText(gr, text, base_x + (txtHeight / 2.0) + (step_x / 2.0),
2344 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
2345 base_x += step_x;
2346 p = p->GetNext();
2347 }
2348 if (others)
2349 {
2350 // including the 'any other' class
2351 gGraphSetFont(gr, font);
2352 gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
2353 &post_x, &post_y);
2354 gGraphDrawText(gr, "AnyOther",
2355 base_x + (txtHeight / 2.0) + (step_x / 2.0),
2356 vsize - labelWidth + txtWidth - 5, M_PI + (M_PI / 2.0));
2357 }
2358
2359 idx = 0;
2360 base_x = start_x;
2361 p = ChartData.GetFirst();
2362 while (p)
2363 {
2364 height =
2365 vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
2366 gGraphSetPen(gr, 192, 192, 192, 255, 1, GGRAPH_PENSTYLE_DOT);
2367 gGraphStrokeLine(gr, base_x + (step_x / 2.0), start_y,
2368 base_x + (step_x / 2.0), base_y - height);
2369 base_x += step_x;
2370 idx++;
2371 p = p->GetNext();
2372 }
2373 if (others)
2374 {
2375 // other unclassified values
2376 height =
2377 vspan *
2378 ((double)
2379 (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetMaxFreq())));
2380 gGraphStrokeLine(gr, base_x + (step_x / 2.0), start_y,
2381 base_x + (step_x / 2.0), base_y - height);
2382 }
2383 idx = 0;
2384 base_x = start_x;
2385 p = ChartData.GetFirst();
2386 while (p)
2387 {
2388 height =
2389 vspan * ((double) (p->GetCount() / (double) (ChartData.GetMaxFreq())));
2390 if (idx == 0)
2391 gGraphMoveToPoint(gr, base_x + (step_x / 2.0), base_y - height);
2392 else
2393 gGraphAddLineToPath(gr, base_x + (step_x / 2.0), base_y - height);
2394 base_x += step_x;
2395 idx++;
2396 p = p->GetNext();
2397 }
2398 if (others)
2399 {
2400 // other unclassified values
2401 height =
2402 vspan *
2403 ((double)
2404 (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetMaxFreq())));
2405 gGraphAddLineToPath(gr, base_x + (step_x / 2.0), base_y - height);
2406 }
2407 gGraphSetPen(gr, 255, 0, 0, 255, 2, GGRAPH_PENSTYLE_SOLID);
2408 gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
2409
2410 // drawing 'scale' labels
2411 pLab = scaleLabels.GetFirst();
2412 while (pLab)
2413 {
2414 gGraphSetFont(gr, font);
2415 strcpy(text, pLab->GetLabel().ToUTF8());
2416 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2417 &post_x, &post_y);
2418 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
2419 base_y - pLab->GetPosition() + (txtHeight / 2.0), 0.0);
2420 gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
2421 gGraphStrokeLine(gr, start_x, base_y - pLab->GetPosition(), end_x,
2422 base_y - pLab->GetPosition());
2423 pLab = pLab->GetNext();
2424 }
2425 // marking the ZERO baseline
2426 gGraphSetFont(gr, font);
2427 strcpy(text, "0");
2428 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight, &post_x,
2429 &post_y);
2430 gGraphDrawText(gr, text, scaleWidth - txtWidth + 5,
2431 base_y + (txtHeight / 2.0), 0.0);
2432 gGraphSetPen(gr, 128, 255, 128, 255, 1, GGRAPH_PENSTYLE_DOT);
2433 gGraphStrokeLine(gr, start_x, base_y, end_x, base_y);
2434
2435 // graphics finalization
2436 gGraphDestroyFont(font);
2437 gGraphDestroyFont(font_big);
2438 if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
2439 || target == CHART_TARGET_IS_PREVIEW)
2440 gGraphGetContextRgbArray(gr, &rgb_array);
2441 if (target == CHART_TARGET_IS_SVG)
2442 gGraphDestroySvgContext(gr);
2443 else if (target == CHART_TARGET_IS_PDF)
2444 gGraphDestroyPdfContext(gr);
2445 else
2446 gGraphDestroyContext(gr);
2447
2448 if (target == CHART_TARGET_IS_PNG)
2449 {
2450 if (rgb_array)
2451 {
2452 // creating the Image from RGB array
2453 const void *img =
2454 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
2455 if (img)
2456 {
2457 char xpath[2024];
2458 strcpy(xpath, ExportPath.ToUTF8());
2459 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
2460 {
2461 wxString msg =
2462 wxT
2463 ("An error occurred while saving\nthe current Char as PNG");
2464 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
2465 MainFrame);
2466 }
2467 gGraphDestroyImage(img);
2468 }
2469 }
2470 }
2471 if (target == CHART_TARGET_IS_PREVIEW)
2472 {
2473 if (rgb_array)
2474 {
2475 // creating the Image from RGB array
2476 wxImage img(hsize, vsize);
2477 img.SetData(rgb_array);
2478 wxBitmap bmp(img);
2479 ChartShow->SetBitmap(bmp);
2480 }
2481 }
2482 if (target == CHART_TARGET_IS_COPY)
2483 {
2484 if (rgb_array)
2485 {
2486 // creating the Image from RGB array
2487 wxImage img(hsize, vsize);
2488 img.SetData(rgb_array);
2489 if (wxTheClipboard->Open())
2490 {
2491 wxTheClipboard->SetData(new wxBitmapDataObject(img));
2492 wxTheClipboard->Close();
2493 }
2494 }
2495 }
2496 }
2497
DoUniquePieChart(int hsize,int vsize,int target,int font_size)2498 void StatsChartDialog::DoUniquePieChart(int hsize, int vsize, int target,
2499 int font_size)
2500 {
2501 // generating a Pie Chart (Unique values)
2502 unsigned char *rgb_array = NULL;
2503 const void *gr = NULL;
2504 const void *font = NULL;
2505 const void *font_big = NULL;
2506 int idx;
2507 MyChartUniqueClass *p;
2508 double radius_x;
2509 double radius_y;
2510 double radius;
2511 double cx;
2512 double cy;
2513 double from;
2514 double step;
2515 char title[1024];
2516 char table[1024];
2517 char column[1024];
2518 double txtWidth;
2519 double txtHeight;
2520 double titleHeight;
2521 double pre_x;
2522 double pre_y;
2523 double post_x;
2524 double post_y;
2525 int title_x;
2526 int title_y;
2527 wxColour colors[8];
2528 int color_idx;
2529 MyPieChartLabels labels;
2530 MyPieChartLabel *pLab;
2531 char text[1024];
2532 double lx;
2533 double ly;
2534 double base_y;
2535 double step_y;
2536 double labelWidth = 0.0;
2537 int others = 0;
2538
2539 // color palette
2540 colors[0] = wxColour(255, 255, 240);
2541 colors[1] = wxColour(255, 240, 255);
2542 colors[2] = wxColour(240, 255, 255);
2543 colors[3] = wxColour(240, 240, 240);
2544 colors[4] = wxColour(255, 192, 192);
2545 colors[5] = wxColour(192, 255, 192);
2546 colors[6] = wxColour(192, 192, 255);
2547 colors[7] = wxColour(192, 192, 192);
2548
2549 // graphics initialization
2550 if (target == CHART_TARGET_IS_SVG)
2551 {
2552 char xpath[2024];
2553 strcpy(xpath, ExportPath.ToUTF8());
2554 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
2555 } else if (target == CHART_TARGET_IS_PDF)
2556 {
2557 char xpath[2024];
2558 strcpy(xpath, ExportPath.ToUTF8());
2559 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
2560 &gr);
2561 } else
2562 gGraphCreateContext(hsize, vsize, &gr);
2563
2564 // background initialization
2565 gGraphSetBrush(gr, 255, 255, 255, 255);
2566 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
2567
2568 // font setup
2569 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_NORMAL,
2570 &font);
2571 gGraphFontSetColor(font, 0, 0, 0, 255);
2572 gGraphCreateFont(font_size, GGRAPH_FONTSTYLE_NORMAL, GGRAPH_FONTWEIGHT_BOLD,
2573 &font_big);
2574 gGraphFontSetColor(font_big, 0, 0, 0, 255);
2575
2576 if (ChartData.GetOtherUniquesFreq() > 0)
2577 others = 1;
2578 // computing TEXT sizes
2579 strcpy(table, Table.ToUTF8());
2580 strcpy(column, Column.ToUTF8());
2581 MainFrame->DoubleQuotedSql(table);
2582 MainFrame->DoubleQuotedSql(column);
2583 sprintf(title, "Dataset: %s.%s [unique values]", table, column);
2584 gGraphSetFont(gr, font_big);
2585 gGraphGetTextExtent(gr, title, &pre_x, &pre_y, &txtWidth, &titleHeight,
2586 &post_x, &post_y);
2587 title_x = (hsize - (int) txtWidth) / 2;
2588 title_y = 5 + (int) titleHeight;
2589 p = ChartData.GetFirst();
2590 while (p)
2591 {
2592 // measuring labels
2593 gGraphSetFont(gr, font);
2594 strcpy(text, p->GetValue().ToUTF8());
2595 if (strlen(text) > 10)
2596 {
2597 text[10] = '.';
2598 text[11] = '.';
2599 text[12] = '\0'; // truncating to max 10 chars
2600 }
2601 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2602 &post_x, &post_y);
2603 if (txtWidth > labelWidth)
2604 labelWidth = txtWidth;
2605 p = p->GetNext();
2606 }
2607 if (others)
2608 {
2609 gGraphGetTextExtent(gr, "AnyOther", &pre_x, &pre_y, &txtWidth, &txtHeight,
2610 &post_x, &post_y);
2611 if (txtWidth > labelWidth)
2612 labelWidth = txtWidth;
2613 }
2614
2615 cx = (double) hsize / 2.0;
2616 cy = (double) vsize / 2.0;
2617 cy += (double) (titleHeight + 10) / 2.0;
2618 radius_x = (double) (hsize - 20) / 2.0;
2619 radius_x -= labelWidth + 10;
2620 radius_y = (double) (vsize - titleHeight - 20) / 2.0;
2621 if (radius_x <= radius_y)
2622 radius = radius_x;
2623 else
2624 radius = radius_y;
2625
2626 // title output
2627 gGraphSetFont(gr, font_big);
2628 gGraphDrawText(gr, title, title_x, title_y, 0.0);
2629
2630 from = 0.0;
2631 idx = 0;
2632 p = ChartData.GetFirst();
2633 while (p)
2634 {
2635 gGraphSetPen(gr, 0, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
2636 color_idx = idx % 8;
2637 gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
2638 colors[color_idx].Blue(), 255);
2639 step =
2640 (M_PI * 2.0) *
2641 ((double) (p->GetCount() / (double) (ChartData.GetTotFreq())));
2642 gGraphDrawCircleSector(gr, cx, cy, radius, from, from + step);
2643 strcpy(text, p->GetValue().ToUTF8());
2644 if (strlen(text) > 10)
2645 {
2646 text[10] = '.';
2647 text[11] = '.';
2648 text[12] = '\0'; // truncating to max 10 chars
2649 }
2650 lx = cx + (radius * 0.90) * cos(from + (step / 2.0));
2651 ly = cy + (radius * 0.90) * sin(from + (step / 2.0));
2652 labels.Add(text, lx, ly);
2653 from += step;
2654 idx++;
2655 p = p->GetNext();
2656 }
2657 if (others)
2658 {
2659 // other unclassified values
2660 color_idx = idx % 8;
2661 gGraphSetBrush(gr, colors[color_idx].Red(), colors[color_idx].Green(),
2662 colors[color_idx].Blue(), 255);
2663 step =
2664 (M_PI * 2.0) *
2665 ((double)
2666 (ChartData.GetOtherUniquesFreq() / (double) (ChartData.GetTotFreq())));
2667 gGraphDrawCircleSector(gr, cx, cy, radius, from, from + step);
2668 lx = cx + (radius * 0.90) * cos(from + (step / 2.0));
2669 ly = cy + (radius * 0.90) * sin(from + (step / 2.0));
2670 labels.Add("AnyOther", lx, ly);
2671 }
2672 // printing class labels
2673 labels.Sort(cx);
2674 step_y = (double) (vsize - 50) / (double) (labels.GetNumLeftLabels() - 1);
2675 base_y = 25.0;
2676 for (idx = 0; idx < labels.GetNumLeftLabels(); idx++)
2677 {
2678 // printing Left labels
2679 pLab = labels.GetLeftLabel(idx);
2680 strcpy(text, pLab->GetLabel().ToUTF8());
2681 gGraphSetFont(gr, font);
2682 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2683 &post_x, &post_y);
2684 gGraphDrawText(gr, text, 10, base_y + (txtHeight / 2.0), 0.0);
2685 gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
2686 gGraphStrokeLine(gr, 10 + txtWidth, base_y, pLab->GetX(), pLab->GetY());
2687 base_y += step_y;
2688 }
2689 step_y = (double) (vsize - 50) / (double) (labels.GetNumRightLabels() - 1);
2690 base_y = 25.0;
2691 for (idx = 0; idx < labels.GetNumRightLabels(); idx++)
2692 {
2693 // printing Right labels
2694 pLab = labels.GetRightLabel(idx);
2695 strcpy(text, pLab->GetLabel().ToUTF8());
2696 gGraphSetFont(gr, font);
2697 gGraphGetTextExtent(gr, text, &pre_x, &pre_y, &txtWidth, &txtHeight,
2698 &post_x, &post_y);
2699 gGraphDrawText(gr, text, hsize - txtWidth - 10,
2700 base_y + (txtHeight / 2.0), 0.0);
2701 gGraphSetPen(gr, 255, 0, 0, 255, 1, GGRAPH_PENSTYLE_SOLID);
2702 gGraphStrokeLine(gr, hsize - txtWidth - 10, base_y, pLab->GetX(),
2703 pLab->GetY());
2704 base_y += step_y;
2705 }
2706
2707 // graphics finalization
2708 gGraphDestroyFont(font);
2709 gGraphDestroyFont(font_big);
2710 if (target == CHART_TARGET_IS_COPY || target == CHART_TARGET_IS_PNG
2711 || target == CHART_TARGET_IS_PREVIEW)
2712 gGraphGetContextRgbArray(gr, &rgb_array);
2713 if (target == CHART_TARGET_IS_SVG)
2714 gGraphDestroySvgContext(gr);
2715 else if (target == CHART_TARGET_IS_PDF)
2716 gGraphDestroyPdfContext(gr);
2717 else
2718 gGraphDestroyContext(gr);
2719
2720 if (target == CHART_TARGET_IS_PNG)
2721 {
2722 if (rgb_array)
2723 {
2724 // creating the Image from RGB array
2725 const void *img =
2726 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
2727 if (img)
2728 {
2729 char xpath[2024];
2730 strcpy(xpath, ExportPath.ToUTF8());
2731 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
2732 {
2733 wxString msg =
2734 wxT
2735 ("An error occurred while saving\nthe current Char as PNG");
2736 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
2737 MainFrame);
2738 }
2739 gGraphDestroyImage(img);
2740 }
2741 }
2742 }
2743 if (target == CHART_TARGET_IS_PREVIEW)
2744 {
2745 if (rgb_array)
2746 {
2747 // creating the Image from RGB array
2748 wxImage img(hsize, vsize);
2749 img.SetData(rgb_array);
2750 wxBitmap bmp(img);
2751 ChartShow->SetBitmap(bmp);
2752 }
2753 }
2754 if (target == CHART_TARGET_IS_COPY)
2755 {
2756 if (rgb_array)
2757 {
2758 // creating the Image from RGB array
2759 wxImage img(hsize, vsize);
2760 img.SetData(rgb_array);
2761 if (wxTheClipboard->Open())
2762 {
2763 wxTheClipboard->SetData(new wxBitmapDataObject(img));
2764 wxTheClipboard->Close();
2765 }
2766 }
2767 }
2768 }
2769
CleanDecimals(char * str)2770 void StatsChartDialog::CleanDecimals(char *str)
2771 {
2772 // suppressing not significative decimal digits
2773 int i;
2774 int len = strlen(str);
2775 for (i = len - 1; i >= 0; i--)
2776 {
2777 if (str[i] == '0')
2778 str[i] = '\0';
2779 else
2780 break;
2781 }
2782 len = strlen(str);
2783 if (str[len - 1] == '.')
2784 str[len - 1] = '\0';
2785 }
2786
OnExit(wxCommandEvent & WXUNUSED (event))2787 void StatsChartDialog::OnExit(wxCommandEvent & WXUNUSED(event))
2788 {
2789 //
2790 // all done:
2791 //
2792 wxDialog::EndModal(wxID_OK);
2793 }
2794
Create(MyFrame * parent,wxString & table,wxString & column,double minx,double miny,double maxx,double maxy)2795 bool MapPreviewDialog::Create(MyFrame * parent, wxString & table,
2796 wxString & column, double minx, double miny,
2797 double maxx, double maxy)
2798 {
2799 //
2800 // creating the dialog
2801 //
2802 MainFrame = parent;
2803 Table = table;
2804 Column = column;
2805 MinX = minx;
2806 MinY = miny;
2807 MaxX = maxx;
2808 MaxY = maxy;
2809 LineColor = wxColour(0, 0, 0);
2810 FillColor = wxColour(192, 192, 192);
2811 if (wxDialog::Create(parent, wxID_ANY, wxT("Map preview")) == false)
2812 return false;
2813 // populates individual controls
2814 CreateControls();
2815 // sets dialog sizer
2816 GetSizer()->Fit(this);
2817 GetSizer()->SetSizeHints(this);
2818 // centers the dialog window
2819 Centre();
2820 return true;
2821 }
2822
CreateControls()2823 void MapPreviewDialog::CreateControls()
2824 {
2825 //
2826 // creating individual control and setting initial values
2827 //
2828 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
2829 this->SetSizer(topSizer);
2830 wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
2831 topSizer->Add(boxSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
2832 // First row: TABLE name
2833 wxBoxSizer *tableSizer = new wxBoxSizer(wxHORIZONTAL);
2834 boxSizer->Add(tableSizer, 0, wxALIGN_RIGHT | wxALL, 0);
2835 wxStaticText *tableLabel =
2836 new wxStaticText(this, wxID_STATIC, wxT("&Table name:"));
2837 tableSizer->Add(tableLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2838 wxTextCtrl *tableCtrl = new wxTextCtrl(this, wxID_ANY, Table,
2839 wxDefaultPosition, wxSize(350, 22),
2840 wxTE_READONLY);
2841 tableCtrl->Enable(false);
2842 tableSizer->Add(tableCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
2843 // second row: COLUMN name
2844 wxBoxSizer *colSizer = new wxBoxSizer(wxHORIZONTAL);
2845 boxSizer->Add(colSizer, 0, wxALIGN_RIGHT | wxALL, 0);
2846 wxStaticText *colLabel =
2847 new wxStaticText(this, wxID_STATIC, wxT("&Column name:"));
2848 colSizer->Add(colLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2849 wxTextCtrl *colCtrl = new wxTextCtrl(this, wxID_ANY, Column,
2850 wxDefaultPosition, wxSize(350, 22),
2851 wxTE_READONLY);
2852 colCtrl->Enable(false);
2853 colSizer->Add(colCtrl, 0, wxALIGN_RIGHT | wxALL, 5);
2854 // third row: Graphics params
2855 wxStaticBox *optBox = new wxStaticBox(this, wxID_STATIC,
2856 wxT("Graphics"),
2857 wxDefaultPosition,
2858 wxDefaultSize);
2859 wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxVERTICAL);
2860 boxSizer->Add(optSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2861 wxBoxSizer *graphSizer = new wxBoxSizer(wxHORIZONTAL);
2862 optSizer->Add(graphSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2863 wxString size[5];
2864 size[0] = wxT("&256");
2865 size[1] = wxT("&512");
2866 size[2] = wxT("&1024");
2867 size[3] = wxT("&2048");
2868 size[4] = wxT("&4196");
2869 SizeCtrl = new wxRadioBox(this, ID_CHART_SIZE,
2870 wxT("&Dimension [pixels]"),
2871 wxDefaultPosition,
2872 wxDefaultSize, 5, size, 1, wxRA_SPECIFY_COLS);
2873 graphSizer->Add(SizeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2874 SizeCtrl->SetSelection(0);
2875 wxBoxSizer *mixSizer = new wxBoxSizer(wxVERTICAL);
2876 graphSizer->Add(mixSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2877 wxBoxSizer *ptSizer = new wxBoxSizer(wxHORIZONTAL);
2878 mixSizer->Add(ptSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2879 wxString symbol[2];
2880 symbol[0] = wxT("&Circle");
2881 symbol[1] = wxT("&Square");
2882 SymbolCtrl = new wxRadioBox(this, ID_MAP_SYMBOL,
2883 wxT("&Point Symbol"),
2884 wxDefaultPosition,
2885 wxDefaultSize, 2, symbol, 1, wxRA_SPECIFY_ROWS);
2886 ptSizer->Add(SymbolCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2887 SymbolCtrl->SetSelection(0);
2888 wxBoxSizer *szSizer = new wxBoxSizer(wxHORIZONTAL);
2889 ptSizer->Add(szSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
2890 wxStaticText *szLabel =
2891 new wxStaticText(this, wxID_STATIC, wxT("&Symbol size:"));
2892 szSizer->Add(szLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2893 SymSizeCtrl = new wxSpinCtrl(this, ID_MAP_SYM_SIZE, wxT("3"),
2894 wxDefaultPosition, wxSize(50, 20),
2895 wxSP_ARROW_KEYS, 1, 32, 3);
2896 szSizer->Add(SymSizeCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2897 wxBoxSizer *lnpgSizer = new wxBoxSizer(wxHORIZONTAL);
2898 mixSizer->Add(lnpgSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2899 wxString fill[2];
2900 fill[0] = wxT("&Yes");
2901 fill[1] = wxT("&No");
2902 FillCtrl = new wxRadioBox(this, ID_MAP_FILL,
2903 wxT("&Interior filling"),
2904 wxDefaultPosition,
2905 wxDefaultSize, 2, fill, 1, wxRA_SPECIFY_ROWS);
2906 lnpgSizer->Add(FillCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2907 FillCtrl->SetSelection(0);
2908 wxBoxSizer *thkSizer = new wxBoxSizer(wxHORIZONTAL);
2909 lnpgSizer->Add(thkSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
2910 wxStaticText *thickLabel =
2911 new wxStaticText(this, wxID_STATIC, wxT("&Line thickness:"));
2912 thkSizer->Add(thickLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2913 ThicknessCtrl = new wxSpinCtrl(this, ID_MAP_THICKNESS, wxT("1"),
2914 wxDefaultPosition, wxSize(50, 20),
2915 wxSP_ARROW_KEYS, 1, 32, 1);
2916 thkSizer->Add(ThicknessCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2917 wxBoxSizer *colorSizer = new wxBoxSizer(wxHORIZONTAL);
2918 mixSizer->Add(colorSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2919 wxBitmap lineBmp;
2920 GetButtonBitmap(LineColor, lineBmp);
2921 LineColorCtrl = new wxBitmapButton(this, ID_MAP_LINE_COL, lineBmp);
2922 colorSizer->Add(LineColorCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2923 wxBitmap fillBmp;
2924 GetButtonBitmap(FillColor, fillBmp);
2925 FillColorCtrl = new wxBitmapButton(this, ID_MAP_FILL_COL, fillBmp);
2926 colorSizer->Add(FillColorCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2927
2928 // creating a control to show the Map preview
2929 wxStaticBox *exBox = new wxStaticBox(this, wxID_ANY,
2930 wxT("Map preview"),
2931 wxDefaultPosition, wxDefaultSize);
2932 wxBoxSizer *showSizer = new wxStaticBoxSizer(exBox, wxHORIZONTAL);
2933 boxSizer->Add(showSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
2934 MapShow = new wxStaticBitmap(this, wxID_ANY,
2935 wxBitmap(), wxDefaultPosition, wxSize(256, 256),
2936 wxBORDER_SUNKEN);
2937 showSizer->Add(MapShow, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2938
2939 // buttons
2940 wxStaticBox *btnBox = new wxStaticBox(this, wxID_STATIC,
2941 wxT("Export as"),
2942 wxDefaultPosition,
2943 wxDefaultSize);
2944 wxBoxSizer *btnSizer = new wxStaticBoxSizer(btnBox, wxVERTICAL);
2945 showSizer->Add(btnSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2946 wxBoxSizer *buttonBox = new wxBoxSizer(wxVERTICAL);
2947 btnSizer->Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
2948 wxButton *copy = new wxButton(this, ID_MAP_COPY, wxT("&Copy"));
2949 buttonBox->Add(copy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2950 wxButton *png = new wxButton(this, ID_MAP_PNG, wxT("&PNG"));
2951 buttonBox->Add(png, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2952 wxButton *svg = new wxButton(this, ID_MAP_SVG, wxT("&SVG"));
2953 buttonBox->Add(svg, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2954 wxButton *pdf = new wxButton(this, ID_MAP_PDF, wxT("&PDF"));
2955 buttonBox->Add(pdf, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2956 wxBoxSizer *exitBox = new wxBoxSizer(wxHORIZONTAL);
2957 boxSizer->Add(exitBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
2958 wxButton *exit = new wxButton(this, wxID_OK, wxT("&Exit"));
2959 exitBox->Add(exit, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
2960 // appends event handler for OK button
2961 Connect(ID_MAP_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
2962 (wxObjectEventFunction) & MapPreviewDialog::OnMapCopy);
2963 Connect(ID_MAP_PNG, wxEVT_COMMAND_BUTTON_CLICKED,
2964 (wxObjectEventFunction) & MapPreviewDialog::OnMapPng);
2965 Connect(ID_MAP_SVG, wxEVT_COMMAND_BUTTON_CLICKED,
2966 (wxObjectEventFunction) & MapPreviewDialog::OnMapSvg);
2967 Connect(ID_MAP_PDF, wxEVT_COMMAND_BUTTON_CLICKED,
2968 (wxObjectEventFunction) & MapPreviewDialog::OnMapPdf);
2969 Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
2970 (wxObjectEventFunction) & MapPreviewDialog::OnExit);
2971 Connect(ID_MAP_LINE_COL, wxEVT_COMMAND_BUTTON_CLICKED,
2972 (wxObjectEventFunction) & MapPreviewDialog::OnLineColor);
2973 Connect(ID_MAP_FILL_COL, wxEVT_COMMAND_BUTTON_CLICKED,
2974 (wxObjectEventFunction) & MapPreviewDialog::OnFillColor);
2975 Connect(ID_MAP_SYMBOL, wxEVT_COMMAND_RADIOBOX_SELECTED,
2976 (wxObjectEventFunction) & MapPreviewDialog::OnSymbolTypeChanged);
2977 Connect(ID_MAP_FILL, wxEVT_COMMAND_RADIOBOX_SELECTED,
2978 (wxObjectEventFunction) & MapPreviewDialog::OnLineThicknessChanged);
2979 Connect(ID_MAP_THICKNESS, wxEVT_COMMAND_TEXT_UPDATED,
2980 (wxObjectEventFunction) & MapPreviewDialog::OnLineThicknessChanged);
2981 Connect(ID_MAP_SIZE, wxEVT_COMMAND_TEXT_UPDATED,
2982 (wxObjectEventFunction) & MapPreviewDialog::OnSymbolSizeChanged);
2983 // showing the current preview
2984 UpdatePreview();
2985 }
2986
GetButtonBitmap(wxColour & color,wxBitmap & bmp)2987 void MapPreviewDialog::GetButtonBitmap(wxColour & color, wxBitmap & bmp)
2988 {
2989 // creating a Bitmap representing some Color
2990 bmp = wxBitmap(64, 24);
2991 wxMemoryDC *dc = new wxMemoryDC(bmp);
2992 dc->SetBrush(wxBrush(color));
2993 dc->DrawRectangle(-1, -1, 66, 26);
2994 delete dc;
2995 }
2996
OnLineColor(wxCommandEvent & WXUNUSED (event))2997 void MapPreviewDialog::OnLineColor(wxCommandEvent & WXUNUSED(event))
2998 {
2999 // color selection
3000 wxColourData initColor;
3001 int ret;
3002 initColor.SetChooseFull(false);
3003 initColor.SetColour(LineColor);
3004 wxColourDialog colorDialog(this, &initColor);
3005 ret = colorDialog.ShowModal();
3006 if (ret == wxID_OK)
3007 {
3008 wxColourData colorData = colorDialog.GetColourData();
3009 wxColour color = colorData.GetColour();
3010 LineColor = wxColour(color.Red(), color.Green(), color.Blue());
3011 wxBitmap bmp;
3012 GetButtonBitmap(LineColor, bmp);
3013 LineColorCtrl->SetBitmapLabel(bmp);
3014 }
3015 UpdatePreview();
3016 }
3017
OnFillColor(wxCommandEvent & WXUNUSED (event))3018 void MapPreviewDialog::OnFillColor(wxCommandEvent & WXUNUSED(event))
3019 {
3020 // color selection
3021 wxColourData initColor;
3022 int ret;
3023 initColor.SetChooseFull(false);
3024 initColor.SetColour(FillColor);
3025 wxColourDialog colorDialog(this, &initColor);
3026 ret = colorDialog.ShowModal();
3027 if (ret == wxID_OK)
3028 {
3029 wxColourData colorData = colorDialog.GetColourData();
3030 wxColour color = colorData.GetColour();
3031 FillColor = wxColour(color.Red(), color.Green(), color.Blue());
3032 wxBitmap bmp;
3033 GetButtonBitmap(FillColor, bmp);
3034 FillColorCtrl->SetBitmapLabel(bmp);
3035 }
3036 UpdatePreview();
3037 }
3038
OnSymbolTypeChanged(wxCommandEvent & WXUNUSED (event))3039 void MapPreviewDialog::OnSymbolTypeChanged(wxCommandEvent & WXUNUSED(event))
3040 {
3041 // symbol type radiobox changed
3042 UpdatePreview();
3043 }
3044
OnFillModeChanged(wxCommandEvent & WXUNUSED (event))3045 void MapPreviewDialog::OnFillModeChanged(wxCommandEvent & WXUNUSED(event))
3046 {
3047 // fill mode radiobox changed
3048 UpdatePreview();
3049 }
3050
OnSymbolSizeChanged(wxCommandEvent & WXUNUSED (event))3051 void MapPreviewDialog::OnSymbolSizeChanged(wxCommandEvent & WXUNUSED(event))
3052 {
3053 // symbol type spincontrol changed
3054 UpdatePreview();
3055 }
3056
OnLineThicknessChanged(wxCommandEvent & WXUNUSED (event))3057 void MapPreviewDialog::OnLineThicknessChanged(wxCommandEvent & WXUNUSED(event))
3058 {
3059 // line thickness spincontrol changed
3060 UpdatePreview();
3061 }
3062
UpdatePreview()3063 void MapPreviewDialog::UpdatePreview()
3064 {
3065 // showing an empty preview map
3066 wxBitmap bmp;
3067 MapShow->SetBitmap(bmp);
3068
3069 // updating the Map Preview
3070 DoMap(256, 256, MAP_TARGET_IS_PREVIEW);
3071 }
3072
DoMap(int hsize,int vsize,int target)3073 void MapPreviewDialog::DoMap(int hsize, int vsize, int target)
3074 {
3075 // drawing the map preview
3076 const void *gr = NULL;
3077 unsigned char *rgb_array = NULL;
3078 char table[1024];
3079 char column[1024];
3080 char sql[4196];
3081 int ret;
3082 char err_msg[2048];
3083 sqlite3_stmt *stmt;
3084 int horz;
3085 int vert;
3086 int h_shift;
3087 int v_shift;
3088 double ratio;
3089 double ext_x = MaxX - MinX;
3090 double ext_y = MaxY - MinY;
3091 bool circle;
3092 int symbol_size;
3093 bool fill;
3094 int thickness;
3095
3096 // computing the rendering ratio
3097 if (ext_x > ext_y)
3098 {
3099 ratio = ext_x / (double) (hsize - 20);
3100 if ((ext_y / ratio) > vsize)
3101 ratio = ext_y / (double) (vsize - 20);
3102 } else
3103 {
3104 ratio = ext_y / (double) (vsize - 20);
3105 if ((ext_x / ratio) > hsize)
3106 ratio = ext_x / (double) (hsize - 20);
3107 }
3108 horz = (int) (ext_x / ratio);
3109 vert = (int) (ext_y / ratio);
3110 horz += 20;
3111 vert += 20;
3112 h_shift = (hsize - horz) / 2;
3113 v_shift = (vsize - vert) / 2;
3114
3115 // retrieving current graphic settings
3116 switch (SymbolCtrl->GetSelection())
3117 {
3118 case 0:
3119 circle = true;
3120 break;
3121 case 1:
3122 circle = false;
3123 break;
3124 };
3125 switch (FillCtrl->GetSelection())
3126 {
3127 case 0:
3128 fill = true;
3129 break;
3130 case 1:
3131 fill = false;
3132 break;
3133 };
3134 symbol_size = SymSizeCtrl->GetValue();
3135 thickness = ThicknessCtrl->GetValue();
3136
3137 // graphics initialization
3138 if (target == MAP_TARGET_IS_SVG)
3139 {
3140 char xpath[2024];
3141 strcpy(xpath, ExportPath.ToUTF8());
3142 gGraphCreateSvgContext(xpath, hsize, vsize, &gr);
3143 } else if (target == MAP_TARGET_IS_PDF)
3144 {
3145 char xpath[2024];
3146 strcpy(xpath, ExportPath.ToUTF8());
3147 gGraphCreatePdfContext(xpath, hsize + 100, vsize + 100, hsize, vsize,
3148 &gr);
3149 } else
3150 gGraphCreateContext(hsize, vsize, &gr);
3151
3152 // background initialization
3153 gGraphSetBrush(gr, 255, 255, 255, 255);
3154 gGraphDrawRectangle(gr, -1, -1, hsize + 2, vsize + 2);
3155
3156 // setting standard graphic setting
3157 gGraphSetPen(gr, LineColor.Red(), LineColor.Green(), LineColor.Blue(), 255,
3158 thickness, GGRAPH_PENSTYLE_SOLID);
3159 gGraphSetBrush(gr, FillColor.Red(), FillColor.Green(), FillColor.Blue(), 255);
3160
3161 ::wxBeginBusyCursor();
3162 strcpy(table, Table.ToUTF8());
3163 strcpy(column, Column.ToUTF8());
3164 MainFrame->DoubleQuotedSql(table);
3165 MainFrame->DoubleQuotedSql(column);
3166 sprintf(sql, "SELECT %s FROM %s", column, table);
3167 ret =
3168 sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
3169 if (ret != SQLITE_OK)
3170 {
3171 sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
3172 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
3173 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3174 ::wxEndBusyCursor();
3175 return;
3176 }
3177 while (1)
3178 {
3179 //
3180 // fetching the result set rows
3181 //
3182 ret = sqlite3_step(stmt);
3183 if (ret == SQLITE_DONE)
3184 break; // end of result set
3185 if (ret == SQLITE_ROW)
3186 {
3187 //
3188 // fetching a row
3189 //
3190 gaiaGeomCollPtr geom = NULL;
3191 if (sqlite3_column_type(stmt, 0) == SQLITE_BLOB)
3192 {
3193 // fetching Geometry
3194 int x;
3195 int y;
3196 const void *blob = sqlite3_column_blob(stmt, 0);
3197 int blob_size = sqlite3_column_bytes(stmt, 0);
3198 geom =
3199 gaiaFromSpatiaLiteBlobWkb((const unsigned char *) blob,
3200 blob_size);
3201 if (geom)
3202 {
3203 // drawing the geometric entity
3204 gaiaPolygonPtr pg = geom->FirstPolygon;
3205 while (pg)
3206 {
3207 // drawing a POLYGON
3208 int iv;
3209 double dx;
3210 double dy;
3211 double z;
3212 double m;
3213 int x;
3214 int y;
3215 int lastX = 0;
3216 int lastY = 0;
3217 int ib;
3218 gaiaRingPtr ring = pg->Exterior;
3219 // exterior border
3220 for (iv = 0; iv < ring->Points; iv++)
3221 {
3222 if (ring->DimensionModel == GAIA_XY_Z)
3223 {
3224 gaiaGetPointXYZ(ring->Coords, iv, &dx, &dy, &z);
3225 } else if (ring->DimensionModel == GAIA_XY_M)
3226 {
3227 gaiaGetPointXYM(ring->Coords, iv, &dx, &dy, &m);
3228 } else if (ring->DimensionModel == GAIA_XY_Z_M)
3229 {
3230 gaiaGetPointXYZM(ring->Coords, iv, &dx, &dy, &z,
3231 &m);
3232 } else
3233 {
3234 gaiaGetPoint(ring->Coords, iv, &dx, &dy);
3235 }
3236 x = (int) ((dx - MinX) / ratio);
3237 y = vert - (int) ((dy - MinY) / ratio);
3238 x += h_shift;
3239 y += v_shift;
3240 if (iv == 0)
3241 {
3242 gGraphMoveToPoint(gr, x, y);
3243 lastX = x;
3244 lastY = y;
3245 } else
3246 {
3247 if (x == lastX && y == lastY)
3248 ;
3249 else
3250 {
3251 gGraphAddLineToPath(gr, x, y);
3252 lastX = x;
3253 lastY = y;
3254 }
3255 }
3256 }
3257 gGraphCloseSubpath(gr);
3258 for (ib = 0; ib < pg->NumInteriors; ib++)
3259 {
3260 // interior borders
3261 ring = pg->Interiors + ib;
3262 for (iv = 0; iv < ring->Points; iv++)
3263 {
3264 if (ring->DimensionModel == GAIA_XY_Z)
3265 {
3266 gaiaGetPointXYZ(ring->Coords, iv, &dx, &dy,
3267 &z);
3268 } else if (ring->DimensionModel == GAIA_XY_M)
3269 {
3270 gaiaGetPointXYM(ring->Coords, iv, &dx, &dy,
3271 &m);
3272 } else if (ring->DimensionModel == GAIA_XY_Z_M)
3273 {
3274 gaiaGetPointXYZM(ring->Coords, iv, &dx, &dy,
3275 &z, &m);
3276 } else
3277 {
3278 gaiaGetPoint(ring->Coords, iv, &dx, &dy);
3279 }
3280 x = (int) ((dx - MinX) / ratio);
3281 y = vert - (int) ((dy - MinY) / ratio);
3282 x += h_shift;
3283 y += v_shift;
3284 if (iv == 0)
3285 {
3286 gGraphMoveToPoint(gr, x, y);
3287 lastX = x;
3288 lastY = y;
3289 } else
3290 {
3291 if (x == lastX && y == lastY)
3292 ;
3293 else
3294 {
3295 gGraphAddLineToPath(gr, x, y);
3296 lastX = x;
3297 lastY = y;
3298 }
3299 }
3300 }
3301 gGraphCloseSubpath(gr);
3302 }
3303 if (fill == true)
3304 gGraphFillPath(gr, GGRAPH_PRESERVE_PATH);
3305 gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
3306 pg = pg->Next;
3307 }
3308 gaiaLinestringPtr ln = geom->FirstLinestring;
3309 while (ln)
3310 {
3311 // drawing a LINESTRING
3312 int iv;
3313 double dx;
3314 double dy;
3315 double z;
3316 double m;
3317 int x;
3318 int y;
3319 int lastX = 0;
3320 int lastY = 0;
3321 for (iv = 0; iv < ln->Points; iv++)
3322 {
3323 if (ln->DimensionModel == GAIA_XY_Z)
3324 {
3325 gaiaGetPointXYZ(ln->Coords, iv, &dx, &dy, &z);
3326 } else if (ln->DimensionModel == GAIA_XY_M)
3327 {
3328 gaiaGetPointXYM(ln->Coords, iv, &dx, &dy, &m);
3329 } else if (ln->DimensionModel == GAIA_XY_Z_M)
3330 {
3331 gaiaGetPointXYZM(ln->Coords, iv, &dx, &dy, &z,
3332 &m);
3333 } else
3334 {
3335 gaiaGetPoint(ln->Coords, iv, &dx, &dy);
3336 }
3337 x = (int) ((dx - MinX) / ratio);
3338 y = vert - (int) ((dy - MinY) / ratio);
3339 x += h_shift;
3340 y += v_shift;
3341 if (iv == 0)
3342 {
3343 gGraphMoveToPoint(gr, x, y);
3344 lastX = x;
3345 lastY = y;
3346 } else
3347 {
3348 if (x == lastX && y == lastY)
3349 ;
3350 else
3351 {
3352 gGraphAddLineToPath(gr, x, y);
3353 lastX = x;
3354 lastY = y;
3355 }
3356 }
3357 }
3358 gGraphStrokePath(gr, GGRAPH_CLEAR_PATH);
3359 ln = ln->Next;
3360 }
3361 gaiaPointPtr pt = geom->FirstPoint;
3362 while (pt)
3363 {
3364 // drawing a POINT
3365 x = (int) ((pt->X - MinX) / ratio);
3366 y = vsize - (int) ((pt->Y - MinY) / ratio);
3367 x += h_shift;
3368 y += v_shift;
3369 if (circle == false)
3370 gGraphDrawRectangle(gr, x - symbol_size,
3371 y - symbol_size, symbol_size * 2,
3372 symbol_size * 2);
3373 else
3374 gGraphDrawEllipse(gr, x - symbol_size, y - symbol_size,
3375 symbol_size * 2, symbol_size * 2);
3376 pt = pt->Next;
3377 }
3378 gaiaFreeGeomColl(geom);
3379 }
3380 }
3381 } else
3382 {
3383 sqlite3_finalize(stmt);
3384 sprintf(err_msg, "SQL error: %s",
3385 sqlite3_errmsg(MainFrame->GetSqlite()));
3386 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
3387 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3388 ::wxEndBusyCursor();
3389 return;
3390 }
3391 }
3392 sqlite3_finalize(stmt);
3393 ::wxEndBusyCursor();
3394
3395 // graphics finalization
3396 if (target == MAP_TARGET_IS_COPY || target == MAP_TARGET_IS_PNG
3397 || target == MAP_TARGET_IS_PREVIEW)
3398 gGraphGetContextRgbArray(gr, &rgb_array);
3399 if (target == MAP_TARGET_IS_SVG)
3400 gGraphDestroySvgContext(gr);
3401 else if (target == MAP_TARGET_IS_PDF)
3402 gGraphDestroyPdfContext(gr);
3403 else
3404 gGraphDestroyContext(gr);
3405
3406 if (target == MAP_TARGET_IS_PNG)
3407 {
3408 if (rgb_array)
3409 {
3410 // creating the Image from RGB array
3411 const void *img =
3412 gGraphCreateRgbImageFromBitmap(rgb_array, hsize, vsize);
3413 if (img)
3414 {
3415 char xpath[2024];
3416 strcpy(xpath, ExportPath.ToUTF8());
3417 if (gGraphImageToPngFile(img, xpath, 6, 0, 0) != GGRAPH_OK)
3418 {
3419 wxString msg =
3420 wxT
3421 ("An error occurred while saving\nthe current Map as PNG");
3422 wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
3423 MainFrame);
3424 }
3425 gGraphDestroyImage(img);
3426 }
3427 }
3428 }
3429 if (target == MAP_TARGET_IS_PREVIEW)
3430 {
3431 if (rgb_array)
3432 {
3433 // creating the Image from RGB array
3434 wxImage img(hsize, vsize);
3435 img.SetData(rgb_array);
3436 wxBitmap bmp(img);
3437 MapShow->SetBitmap(bmp);
3438 }
3439 }
3440 if (target == MAP_TARGET_IS_COPY)
3441 {
3442 if (rgb_array)
3443 {
3444 // creating the Image from RGB array
3445 wxImage img(hsize, vsize);
3446 img.SetData(rgb_array);
3447 if (wxTheClipboard->Open())
3448 {
3449 wxTheClipboard->SetData(new wxBitmapDataObject(img));
3450 wxTheClipboard->Close();
3451 }
3452 }
3453 }
3454 }
3455
OnMapCopy(wxCommandEvent & WXUNUSED (event))3456 void MapPreviewDialog::OnMapCopy(wxCommandEvent & WXUNUSED(event))
3457 {
3458 // copying the current Map to the Clipboard
3459 int hsize;
3460 int vsize;
3461 switch (SizeCtrl->GetSelection())
3462 {
3463 case 0:
3464 hsize = 256;
3465 vsize = 256;
3466 break;
3467 case 1:
3468 hsize = 512;
3469 vsize = 512;
3470 break;
3471 case 2:
3472 hsize = 1024;
3473 vsize = 1024;
3474 break;
3475 case 3:
3476 hsize = 2048;
3477 vsize = 2048;
3478 break;
3479 case 4:
3480 hsize = 4196;
3481 vsize = 4196;
3482 break;
3483 };
3484
3485 // exporting the Map as COPY
3486 DoMap(hsize, vsize, MAP_TARGET_IS_COPY);
3487 }
3488
OnMapPng(wxCommandEvent & WXUNUSED (event))3489 void MapPreviewDialog::OnMapPng(wxCommandEvent & WXUNUSED(event))
3490 {
3491 // exporting the current Chart as PNG
3492 int hsize;
3493 int vsize;
3494 switch (SizeCtrl->GetSelection())
3495 {
3496 case 0:
3497 hsize = 256;
3498 vsize = 256;
3499 break;
3500 case 1:
3501 hsize = 512;
3502 vsize = 512;
3503 break;
3504 case 2:
3505 hsize = 1024;
3506 vsize = 1024;
3507 break;
3508 case 3:
3509 hsize = 2048;
3510 vsize = 2048;
3511 break;
3512 case 4:
3513 hsize = 4196;
3514 vsize = 4196;
3515 break;
3516 };
3517
3518 // asking an export path
3519 int ret;
3520 wxString lastDir;
3521 wxString fileList = wxT("PNG Image (*.png)|*.png");
3522 wxFileDialog fileDialog(MainFrame, wxT("saving the current Map as PNG"),
3523 wxT(""), wxT("MapExport"), fileList,
3524 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3525 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3526 lastDir = MainFrame->GetLastDirectory();
3527 if (lastDir.Len() >= 1)
3528 fileDialog.SetDirectory(lastDir);
3529 ret = fileDialog.ShowModal();
3530 if (ret == wxID_OK)
3531 {
3532 wxFileName file(fileDialog.GetPath());
3533 lastDir = file.GetPath();
3534 MainFrame->SetLastDirectory(lastDir);
3535 wxString path = file.GetPath();
3536 path += file.GetPathSeparator();
3537 path += file.GetName();
3538 path += wxT(".png");
3539 ExportPath = path;
3540 } else
3541 return;
3542
3543 // exporting the Map as PNG
3544 DoMap(hsize, vsize, MAP_TARGET_IS_PNG);
3545 }
3546
OnMapSvg(wxCommandEvent & WXUNUSED (event))3547 void MapPreviewDialog::OnMapSvg(wxCommandEvent & WXUNUSED(event))
3548 {
3549 // exporting the current Map as SVG
3550 int hsize;
3551 int vsize;
3552 switch (SizeCtrl->GetSelection())
3553 {
3554 case 0:
3555 hsize = 256;
3556 vsize = 256;
3557 break;
3558 case 1:
3559 hsize = 512;
3560 vsize = 512;
3561 break;
3562 case 2:
3563 hsize = 1024;
3564 vsize = 1024;
3565 break;
3566 case 3:
3567 hsize = 2048;
3568 vsize = 2048;
3569 break;
3570 case 4:
3571 hsize = 4196;
3572 vsize = 4196;
3573 break;
3574 };
3575
3576 // asking an export path
3577 int ret;
3578 wxString lastDir;
3579 wxString fileList = wxT("SVG Vector Image (*.svg)|*.svg");
3580 wxFileDialog fileDialog(MainFrame, wxT("saving the current Map as SVG"),
3581 wxT(""), wxT("MapExport"), fileList,
3582 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3583 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3584 lastDir = MainFrame->GetLastDirectory();
3585 if (lastDir.Len() >= 1)
3586 fileDialog.SetDirectory(lastDir);
3587 ret = fileDialog.ShowModal();
3588 if (ret == wxID_OK)
3589 {
3590 wxFileName file(fileDialog.GetPath());
3591 lastDir = file.GetPath();
3592 MainFrame->SetLastDirectory(lastDir);
3593 wxString path = file.GetPath();
3594 path += file.GetPathSeparator();
3595 path += file.GetName();
3596 path += wxT(".svg");
3597 ExportPath = path;
3598 } else
3599 return;
3600
3601
3602 // exporting the Map as SVG
3603 DoMap(hsize, vsize, MAP_TARGET_IS_SVG);
3604 }
3605
OnMapPdf(wxCommandEvent & WXUNUSED (event))3606 void MapPreviewDialog::OnMapPdf(wxCommandEvent & WXUNUSED(event))
3607 {
3608 // exporting the current Map as PDF
3609 double ext_x = MaxX - MinX;
3610 double ext_y = MaxY - MinY;
3611 int hsize = (int) (12.8 * 300.0);
3612 int vsize = (int) (9.0 * 300.0);
3613 hsize -= 100; // margin
3614 vsize -= 100; // margin
3615
3616 if (ext_y > ext_x)
3617 {
3618 // portrait, not landscape orientation
3619 int swap = hsize;
3620 hsize = vsize;
3621 vsize = swap;
3622 }
3623 // asking an export path
3624 int ret;
3625 wxString lastDir;
3626 wxString fileList = wxT("PDF Document (*.pdf)|*.pdf");
3627 wxFileDialog fileDialog(MainFrame, wxT("saving the current Map as PDF"),
3628 wxT(""), wxT("MapExport"), fileList,
3629 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3630 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3631 lastDir = MainFrame->GetLastDirectory();
3632 if (lastDir.Len() >= 1)
3633 fileDialog.SetDirectory(lastDir);
3634 ret = fileDialog.ShowModal();
3635 if (ret == wxID_OK)
3636 {
3637 wxFileName file(fileDialog.GetPath());
3638 lastDir = file.GetPath();
3639 MainFrame->SetLastDirectory(lastDir);
3640 wxString path = file.GetPath();
3641 path += file.GetPathSeparator();
3642 path += file.GetName();
3643 path += wxT(".pdf");
3644 ExportPath = path;
3645 } else
3646 return;
3647
3648
3649 // exporting the Map as PDF
3650 DoMap(hsize, vsize, MAP_TARGET_IS_PDF);
3651 }
3652
OnExit(wxCommandEvent & WXUNUSED (event))3653 void MapPreviewDialog::OnExit(wxCommandEvent & WXUNUSED(event))
3654 {
3655 //
3656 // all done:
3657 //
3658 wxDialog::EndModal(wxID_OK);
3659 }
3660