-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSvgTool.py
148 lines (128 loc) · 5.13 KB
/
SvgTool.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#! /usr/bin/python3
'''
svgtool: Scalable Vector Graphics tool
@author: hm
'''
import os.path
import sys
import re
import datetime
import math
import functools
import StringUtils
from I18N import I18N
VERSION = '2023.03.22.00'
gSvgToolPeriod = 4
class Logger:
def log(self, msg, level: int=0):
print(msg)
def error(self, msg):
self.log('+++ ' + msg)
class SvgTool:
'''Creates SVG data.
'''
def __init__(self, i18n: I18N=None):
'''Constructor.
@param i18n: the I18N instance
'''
self._columns = []
self._rexprNo = re.compile(
r'^\s*[+-]?\d+([.,]\d+([eE][+-]?\d+)?)?\s*$')
self._color = 'black'
self._strokeWidth = 2
self._output = []
self._fontSize = 10
self._colors = ['black', 'red', 'orange', 'magenta', 'green', 'brown']
self._logger = Logger()
self.outputFileType = 'html'
self._legendRows = None
if i18n == None:
i18n = I18N('de en')
i18n.read('svgtool.i18n')
self.tableTitle = i18n.replaceI18n('<table class="sun-table"><thead><tr><th></th><th>i18n(svg.average)</th>'
+ '<th>i18n(svg.minimum)</th><th>i18n(svg.maximum)</th><th>i18n(svg.conclusion)</th>'
+ '<th class="svg-left">i18n(svg.notice)</></tr></thead>') + '\n'
def htmlEnd(self):
if self.outputFileType == 'html':
self._output.append('</body>\n</html>')
def htmlStart(self, title):
'''Starts a HTML script.
'''
if self.outputFileType == 'html':
self._output.append('<html>\n<body>\n<h1>{}</h1>\n'.format(title))
def simpleLine(self, x1, y1, x2, y2, strokeWidth, properties=None, color=None):
if strokeWidth == 1:
line = '\n<line x1="{}" y1="{}" x2="{}" y2="{}" stroke="{}" {}/>'.format(
x1, y1, x2, y2, color if color != None else self._color, properties if properties != None else '')
else:
line = '\n<line x1="{}" y1="{}" x2="{}" y2="{}" stroke="{}" stroke-width="{}" {}/>'.format(
x1, y1, x2, y2, color if color != None else self._color, strokeWidth, properties if properties != None else '')
self._output.append(line)
def simpleText(self, x, y, text):
self._output.append('<text x="{}" y="{}" fill="{}" font-size="{}">{}</text>'.format(
x, y, self._color, self._fontSize, text))
def svgEnd(self):
self._output.append('</svg>\n')
def svgStart(self, width, height):
'''Starts the SVG block.
@param width: the width of the SVG area
@param height: the height of the SVG area
'''
self._output.append(
'<svg height="{}" width="{}">\n'.format(height, width))
def usage():
'''Returns an info about usage
'''
return """svgtool [<opts>] <command>
Builds Scalable Vector Graphics embedded in HTML.
GLOBAL_OPTS
GLOBAL_MODES
<command>:
x-y-diagram <input-file> <output-file> <opts>
<output-file>
'-': output will be put to the stdout otherwise: the HTML will be put to this file
<opt>:
--width=<width>
the width of the drawing area in pixel. Default: 1000
--height=<height>
the height of the drawing area in pixel. Default: 500
--axis-area-width=<width>
the width of the area containing the axis and the related labels (for x and y axis). Default: 15
--max-average-quotient=<value>
if max/avg(values) < maxAvgQuotient: no clipping is done. Default: 5
--moving-average=<window-length>
prepare data with "moving average": for each value a "window" (values and neigbours, symetic left
and right) is used to build the average: this average is used instead of the value
default windows width: 5
--spread-range=<value>
a % value: only data in this range will be displayed. Default: 90
--spread-factor
if abs(extremum-endOfRange) / range <= spreadFactor: the range is expanded to the extremum
Example: data [0.5, 1, 2, 7, 99] max=7 min=1 range=7-1=6
abs(0.5-7)/6=1.099 1.099<1.1 => _min=0.5
abs(99-1)/6=16 16>1.1 => _max=99
--title=<title>
Default: Diagram
example:
svgtool -v2 x-y-diagram /tmp/sinus.csv /tmp/sinus.html --width=1920 --height=1024 "--title=Trigonometric functions from [0, 4*pi]"
"""
def main(argv):
'''The main routine.
@param argv: the program arguments, e.g. ['/usr/local/bin/svgtool', 'run']
'''
if len(argv) > 2 and argv[0] == 'example':
global gSvgToolPeriod
try:
gSvgToolPeriod = int(argv[1])
except ValueError:
pass
tool = SvgTool()
if len(argv) > 0 and argv[0] == 'image':
tool.setTitles(['Zeit', 'Temperatur', 'Leistung'])
for ix in range(100):
tool.addRow([500 + ix, 20 + ix % 10 / 10, 300 + ix % 47 * 5])
tool.diagram('example.html', [])
print("example.html created")
return 0
if __name__ == '__main__':
main(sys.argv[1:])