diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index 401b6f3..8d0d2eb 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: m1730-generator - image: git.baumann.gr/adebaumann/m1730-generator:0.77 + image: git.baumann.gr/adebaumann/m1730-generator:0.78 imagePullPolicy: Always ports: - containerPort: 5000 diff --git a/web/app.py b/web/app.py index 955d1d3..8748f67 100644 --- a/web/app.py +++ b/web/app.py @@ -8,7 +8,7 @@ from fontTools.pens.svgPathPen import SVGPathPen app = Flask(__name__) -VERSION = "0.77" +VERSION = "0.78" _LOGO_PATH = pathlib.Path(__file__).parent / 'static' / 'logo.png' _LOGO_B64 = base64.b64encode(_LOGO_PATH.read_bytes()).decode() @@ -334,8 +334,8 @@ def _text_to_paths(text, x, y, font_size, anchor='start', fill='#1a1a1a', wrap_t def generate_svg(unit, min_val, max_val, range_label, big_ticks, small_ticks, label_count, - use_paths=True, log_scale=False, custom_labels=None, label_size=9): - if log_scale: + use_paths=True, scale_type='linear', custom_labels=None, label_size=9): + if scale_type == 'log': if min_val <= 0 or max_val <= 0: raise ValueError("Logarithmic scale requires min and max values greater than 0.") lmin, lmax = math.log(min_val), math.log(max_val) @@ -348,6 +348,20 @@ def generate_svg(unit, min_val, max_val, range_label, big_ticks, small_ticks, la def major_value(i): return min_val * (max_val / min_val) ** (i / big_ticks) + + elif scale_type == 'sqrt': + if min_val < 0: + raise ValueError("Square-root scale requires min value ≥ 0.") + span = max_val - min_val + if span <= 0: + raise ValueError("Square-root scale requires max value greater than min.") + + def value_to_x(v): + return ZERO_X + SCALE_LEN * math.sqrt((v - min_val) / span) + + def major_value(i): + return min_val + span * (i / big_ticks) ** 2 + else: span = max_val - min_val @@ -357,7 +371,7 @@ def generate_svg(unit, min_val, max_val, range_label, big_ticks, small_ticks, la return ZERO_X + SCALE_LEN * (v - min_val) / span def major_value(i): - return min_val + (max_val - min_val) * i / big_ticks + return min_val + span * i / big_ticks big_interval = SCALE_LEN / big_ticks # Major ticks are always physically evenly spaced; only their values differ. @@ -474,14 +488,14 @@ def generate(): small_ticks = max(0, min(20, int(request.form.get('small_ticks', 4)))) label_count = max(2, int(request.form.get('label_count', 6))) use_paths = request.form.get('output_mode', 'paths') == 'paths' - log_scale = request.form.get('scale_type', 'linear') == 'log' + scale_type = request.form.get('scale_type', 'linear') custom_labels = [s.strip() for s in request.form.get('labels', '').split(',') if s.strip()] or None label_size = max(0.5, min(25.0, float(request.form.get('label_size', 9)))) try: svg = generate_svg(unit, min_val, max_val, range_label, big_ticks, small_ticks, - label_count, use_paths, log_scale, custom_labels, label_size) + label_count, use_paths, scale_type, custom_labels, label_size) except ValueError as err: return Response(str(err), status=400, mimetype='text/plain') return Response(svg, mimetype='image/svg+xml') diff --git a/web/templates/index.html b/web/templates/index.html index 7119072..23cdecd 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -318,6 +318,8 @@
+
@@ -433,11 +435,13 @@ } if (btn.dataset.scale !== undefined) { document.getElementById('scale-type').value = btn.dataset.scale; + const minInput = document.querySelector('input[name="min"]'); + const maxInput = document.querySelector('input[name="max"]'); if (btn.dataset.scale === 'log') { - const minInput = document.querySelector('input[name="min"]'); - const maxInput = document.querySelector('input[name="max"]'); if (!(parseFloat(minInput.value) > 0)) minInput.value = '1'; if (!(parseFloat(maxInput.value) > 0)) maxInput.value = '100'; + } else if (btn.dataset.scale === 'sqrt') { + if (parseFloat(minInput.value) < 0) minInput.value = '0'; } } doGenerate();