""" Visual Analog Scale (VAS) Layout A continuous line scale with no tick marks or discrete bins. Annotators click/drag to a position, returning a precise float value. Psychophysically superior to Likert scales for fine-grained judgments. Research: Stevens (1957) "On the Psychophysical Law"; standard in clinical pain assessment. """ import logging from .identifier_utils import ( safe_generate_layout, generate_element_identifier, generate_validation_attribute, escape_html_content, generate_layout_attributes ) logger = logging.getLogger(__name__) # Defaults DEFAULT_MIN = 0 DEFAULT_MAX = 100 DEFAULT_SHOW_VALUE = False def generate_vas_layout(annotation_scheme): """ Generate HTML for a Visual Analog Scale interface. Args: annotation_scheme (dict): Configuration including: - name: Schema identifier - description: Display description - left_label: Label for the left endpoint - right_label: Label for the right endpoint - min_value: Minimum value (default 0) - max_value: Maximum value (default 100) - show_value: Whether to show numeric value after selection (default False) - precision: Decimal places to round to (default 1) Returns: tuple: (html_string, key_bindings) """ return safe_generate_layout(annotation_scheme, _generate_vas_layout_internal) def _generate_vas_layout_internal(annotation_scheme): schema_name = annotation_scheme['name'] description = annotation_scheme['description'] left_label = annotation_scheme.get('left_label', '') right_label = annotation_scheme.get('right_label', '') min_value = annotation_scheme.get('min_value', DEFAULT_MIN) max_value = annotation_scheme.get('max_value', DEFAULT_MAX) show_value = annotation_scheme.get('show_value', DEFAULT_SHOW_VALUE) precision = annotation_scheme.get('precision', 1) layout_attrs = generate_layout_attributes(annotation_scheme) validation = generate_validation_attribute(annotation_scheme) identifiers = generate_element_identifier(schema_name, schema_name, "range") # The key difference from slider: a fine precision-based step (vs the # slider's integer ticks), no tick marks, no value display by default, # minimal styling. Step is derived from precision so the scale is # effectively continuous (precision=1 → step=0.1, precision=2 → 0.01). step_value = 10 ** -precision if precision > 0 else 1 initial_value = round((min_value + max_value) / 2, precision) value_display = "" if show_value: value_display = f"""
""" html = f"""
{escape_html_content(description)}
{escape_html_content(left_label)} {escape_html_content(right_label)}
{value_display}
""" # Inline JS to round value and update display if show_value: html += f""" """ logger.info(f"Generated VAS layout for {schema_name}") return html, []