import base64
import pathlib
from flask import Flask, render_template, request, Response
from html import escape
app = Flask(__name__)
_LOGO_PATH = pathlib.Path(__file__).parent / 'static' / 'logo.png'
_LOGO_B64 = base64.b64encode(_LOGO_PATH.read_bytes()).decode()
_FONT_PATH = pathlib.Path('/usr/local/share/fonts/г/ГОСТ_тип_А.ttf')
_FONT_B64 = base64.b64encode(_FONT_PATH.read_bytes()).decode()
_FONT_FACE = (
''
)
# SVG absolute coordinate constants (1 user unit = 1 mm)
ZERO_X = 60.844130 # x of the zero/left tick
MAX_X = 180.251230 # x of the full-scale/right tick
BAR_Y = 107.54670 # y at the top of the scale bar (tick baseline)
SCALE_LEN = MAX_X - ZERO_X # 119.4071 mm
BIG_H = 5.0895 # major tick height
SMALL_H = 2.6683 # minor tick height
_UNIT_AREA_WIDTH = 18.445 # canvas mm available for the unit label
_UNIT_SCALE_X = 0.96486402
_UNIT_CHAR_EM = 0.65 # approximate advance-width ratio for GOST typ A
def _unit_font_size(unit: str) -> float:
n = max(1, len(unit))
return min(18.7981, _UNIT_AREA_WIDTH / (n * _UNIT_SCALE_X * _UNIT_CHAR_EM))
def _fmt(v: float) -> str:
if v == int(v):
return str(int(v))
return f"{v:.4g}"
def generate_svg(unit, min_val, max_val, range_label, big_ticks, small_ticks, label_count):
big_interval = SCALE_LEN / big_ticks
big_xs = [ZERO_X + i * big_interval for i in range(big_ticks + 1)]
label_count = max(2, min(label_count, big_ticks + 1))
label_indices = [round(k * big_ticks / (label_count - 1)) for k in range(label_count)]
parts = [
'',
'']
return '\n'.join(parts)
@app.route('/')
def index():
return render_template('index.html', logo_b64=_LOGO_B64)
@app.route('/generate', methods=['POST'])
def generate():
unit = request.form.get('unit', '%')
min_val = float(request.form.get('min', 0))
max_val = float(request.form.get('max', 100))
range_label = request.form.get('range_label', '5mA')
big_ticks = max(1, min(50, int(request.form.get('big_ticks', 10))))
small_ticks = max(0, min(20, int(request.form.get('small_ticks', 4))))
label_count = max(2, int(request.form.get('label_count', 6)))
svg = generate_svg(unit, min_val, max_val, range_label, big_ticks, small_ticks, label_count)
return Response(svg, mimetype='image/svg+xml')
if __name__ == '__main__':
app.run(debug=True)