1 package com.github.celldynamics.quimp.utils.graphics.svg;
2
3 import java.awt.Rectangle;
4 import java.io.IOException;
5 import java.io.PrintWriter;
6
7 import com.github.celldynamics.quimp.QColor;
8 import com.github.celldynamics.quimp.geom.ExtendedVector2d;
9
10 import ij.IJ;
11
12
13
14
15
16
17
18
19
20 public abstract class SVGwritter {
21
22
23
24
25
26
27
28
29 public static void writeHeader(PrintWriter osw, Rectangle d) throws IOException {
30 Rectangle d1 = new Rectangle(d);
31 d1.grow(1, 1);
32 osw.write("<?xml version=\"1.0\" standalone=\"no\"?>\n");
33 osw.write("<svg width=\"15cm\" height=\"15cm\" viewBox=\"" + d1.x + " " + d1.y + " " + d1.width
34 + " " + d1.height + "\" "
35 + "xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\">\n");
36 osw.write("\n");
37
38 osw.write("<rect x=\"" + d.getX() + "\" y=\"" + d.getY() + "\" width=\"" + d.getWidth()
39 + "\" height=\"" + d.getHeight() + "\" "
40 + "style=\"fill:rgb(100.0%,100.0%,100.0%);stroke-width:0.01;"
41 + "stroke:rgb(0.0%,0.0%,0.0%)\"/>\n\n");
42 }
43
44
45
46
47
48
49
50 public abstract void draw(PrintWriter osw) throws IOException;
51
52
53
54
55
56
57
58 public static class Qcircle extends SVGwritter {
59
60
61
62
63 public double x1;
64
65
66
67 public double y1;
68
69
70
71
72 public double radius;
73
74
75
76
77 public QColor colour;
78
79
80
81
82 public QColor strokecolour;
83
84
85
86
87 public double thickness;
88
89
90
91
92
93
94
95
96 public Qcircle(double x1, double y1, double radius) {
97 this.x1 = x1;
98 this.y1 = y1;
99 this.radius = radius;
100 colour = new QColor(0, 0, 0);
101 strokecolour = colour;
102 thickness = 0.0;
103 }
104
105
106
107
108
109
110 @Override
111 public void draw(PrintWriter osw) throws IOException {
112 String col;
113 if (colour == null) {
114 col = "none";
115 } else {
116 col = colour.getColorSVG();
117 }
118
119 osw.write("<circle cx=\"" + x1 + "\"" + " cy=\"" + y1 + "\"" + " r=\"" + radius + "\""
120 + " fill=\"" + col + "\"" + " stroke=\"" + strokecolour.getColorSVG() + "\""
121 + " stroke-width=\"" + thickness + "\"/>\n");
122
123 }
124 }
125
126
127
128
129
130
131
132 public static class Qline extends SVGwritter {
133
134
135
136
137 public double x1;
138
139
140
141 public double y1;
142
143
144
145 public double x2;
146
147
148
149 public double y2;
150
151
152
153
154 public double thickness;
155
156
157
158
159 public QColor colour;
160
161
162
163
164
165
166
167
168
169 public Qline(double xx1, double yy1, double xx2, double yy2) {
170 x1 = xx1;
171 x2 = xx2;
172 y1 = yy1;
173 y2 = yy2;
174
175 thickness = 1;
176 colour = new QColor(0, 0, 0);
177 }
178
179
180
181
182
183
184 public double length() {
185 return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
186 }
187
188
189
190
191
192
193
194 @Override
195 public void draw(PrintWriter osw) throws IOException {
196 osw.write("<line x1=\"" + x1 + "\" y1=\"" + y1 + "\" x2=\"" + x2 + "\" y2=\"" + y2 + "\" ");
197 osw.write("style=\"stroke:" + colour.getColorSVG() + ";stroke-width:" + thickness + "\"/>\n");
198 }
199 }
200
201
202
203
204
205
206
207 public static class Qtext extends SVGwritter {
208
209
210
211
212 public String text;
213
214
215
216
217 public double size;
218
219
220
221
222 public QColor colour;
223
224
225
226
227 public String font;
228
229
230
231
232 public ExtendedVector2d pos;
233
234
235
236
237 public double letterSpacing = 0;
238
239
240
241
242 public String textAnchor = "start";
243
244
245
246
247
248
249
250
251
252 public Qtext(String t, double s, String f, ExtendedVector2d pos) {
253 text = t;
254 size = s;
255 font = f;
256 this.pos = pos;
257 colour = new QColor(0, 0, 0);
258 }
259
260
261
262
263
264
265 public int length() {
266 return text.length();
267 }
268
269
270
271
272
273
274
275 @Override
276 public void draw(PrintWriter osw) throws IOException {
277 osw.write("\n<text x=\"" + pos.getX() + "\" y=\"" + pos.getY() + "\" "
278 + "style=\"font-family: " + font + ";font-size: " + size + ";fill: "
279 + colour.getColorSVG() + ";letter-spacing: " + letterSpacing + ";text-anchor: "
280 + textAnchor + "\">" + text + "</text>");
281
282 }
283 }
284
285
286
287
288
289
290
291 public static class QPolarAxes extends SVGwritter {
292 private Rectangle rect;
293
294
295
296
297 public QColor colour;
298
299
300
301
302 public double thickness;
303
304
305
306
307 public boolean angleLabel = false;
308
309
310
311
312 public double fontSize = 0.2;
313
314
315
316
317
318
319 public double[] radiusLabels = null;
320
321
322
323
324
325
326 public int numofIntCircles = 5;
327
328
329
330
331
332
333 public QPolarAxes(Rectangle rect) {
334 this.rect = rect;
335 colour = new QColor(0.5, 0.5, 0.5);
336 thickness = 0.01;
337 }
338
339
340
341
342
343
344
345 @Override
346 public void draw(PrintWriter osw) throws IOException {
347
348 double x0 = rect.getLocation().getX() + rect.getWidth() / 2;
349 double y0 = rect.getLocation().getY() + rect.getHeight() / 2;
350 double radius = rect.getHeight() / 2;
351
352
353 Qcircle qcmain = new Qcircle(x0, y0, radius);
354 qcmain.colour = new QColor(1, 1, 1);
355 qcmain.strokecolour = colour;
356 qcmain.thickness = thickness;
357 qcmain.draw(osw);
358
359
360 for (int a = 0; a < 360; a += 20) {
361 double xend = radius * Math.cos(Math.toRadians(a)) + x0;
362 double yend = radius * Math.sin(Math.toRadians(a)) + y0;
363 Qline ql = new Qline(x0, y0, xend, yend);
364 ql.thickness = thickness;
365 ql.colour = colour;
366 ql.draw(osw);
367
368
369 if (angleLabel) {
370 Qtext qt = new Qtext(Integer.toString(a), fontSize, "New Roman",
371 new ExtendedVector2d(xend, yend));
372
373 if (a < 90 || a > 270) {
374 qt.textAnchor = "start";
375 } else {
376 qt.textAnchor = "end";
377 }
378 qt.draw(osw);
379 }
380 }
381
382 double d = radius / (numofIntCircles + 1);
383 double gridrad = d;
384 int i = 0;
385 do {
386 Qcircle g1 = new Qcircle(x0, y0, gridrad);
387 g1.colour = null;
388 g1.strokecolour = colour;
389 g1.thickness = thickness;
390 g1.draw(osw);
391
392
393 if (radiusLabels != null && i < numofIntCircles) {
394 String st = IJ.d2s(radiusLabels[i], 2, 4);
395 double x = gridrad * Math.cos(Math.toRadians(160)) + x0;
396 double y = gridrad * Math.sin(Math.toRadians(160)) + y0;
397 Qtext qt = new Qtext(st, fontSize - 0.04, "New Roman", new ExtendedVector2d(x, y));
398
399 qt.textAnchor = "middle";
400 qt.draw(osw);
401 }
402 gridrad += d;
403 } while (++i < numofIntCircles);
404
405
406 {
407 Qcircle qc = new Qcircle(rect.getLocation().getX() + rect.getWidth() / 2,
408 rect.getLocation().getY() + rect.getHeight() / 2, thickness * 4);
409 qc.colour = new QColor(1, 0, 0);
410 qc.draw(osw);
411 }
412
413
414 {
415 Qcircle qc = new Qcircle(radius * Math.cos(Math.toRadians(0)) + x0,
416 radius * Math.sin(Math.toRadians(0)) + y0, thickness * 4);
417 qc.colour = new QColor(0, 1, 0);
418 qc.draw(osw);
419 }
420
421
422 {
423 Qcircle qc = new Qcircle(radius * Math.cos(Math.toRadians(180)) + x0,
424 radius * Math.sin(Math.toRadians(180)) + y0, thickness * 4);
425 qc.colour = new QColor(0, 0, 1);
426 qc.draw(osw);
427 }
428
429 }
430 }
431
432
433
434
435
436
437
438 public static class QScaleBar extends SVGwritter {
439
440 private double length;
441 private String units;
442 private int value;
443
444
445
446 public double thickness;
447
448
449
450 public QColor colour;
451 private ExtendedVector2d location;
452 private SVGwritter.Qtext text;
453
454
455
456
457
458
459
460
461
462 public QScaleBar(ExtendedVector2d l, String u, int v, double s) {
463 location = l;
464 units = u;
465 value = v;
466 thickness = 1;
467 colour = new QColor(1, 1, 1);
468 this.setScale(s);
469 text = new SVGwritter.Qtext(IJ.d2s(value, 0) + units, 6, "Courier", l);
470 text.colour = colour;
471 }
472
473
474
475
476
477
478 public void setScale(double s) {
479 length = value / s;
480 }
481
482
483
484
485
486
487
488 @Override
489 public void draw(PrintWriter osw) throws IOException {
490 SVGwritter.Qline body;
491
492 double tickSize = 2 * thickness;
493
494 ExtendedVector2dimp/geom/ExtendedVector2d.html#ExtendedVector2d">ExtendedVector2d end = new ExtendedVector2d(location.getX(), location.getY());
495 end.addVec(new ExtendedVector2d(length, 0));
496 body = new SVGwritter.Qline(location.getX(), location.getY(), end.getX(), end.getY());
497 body.thickness = thickness;
498 body.colour = colour;
499
500 SVGwritter.Qline ltick;
501 SVGwritter.Qline rtick;
502 ltick = new SVGwritter.Qline(location.getX(), location.getY() + tickSize, location.getX(),
503 location.getY() - tickSize);
504 rtick = new SVGwritter.Qline(end.getX(), end.getY() + tickSize, end.getX(),
505 end.getY() - tickSize);
506 ltick.thickness = thickness;
507 ltick.colour = colour;
508 rtick.thickness = thickness;
509 rtick.colour = colour;
510
511 ltick.draw(osw);
512 rtick.draw(osw);
513 body.draw(osw);
514
515
516 int textLength = 2 + Integer.toString(value).length();
517 textLength = textLength * 4;
518 double textDis = (body.length() - textLength) / 2;
519 text.pos = new ExtendedVector2d(location.getX() + textDis, location.getY() - 2);
520 text.draw(osw);
521 }
522
523 }
524 }