Compare commits
4 Commits
912e209b80
...
7a57c29202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a57c29202 | ||
|
|
b461d759e5 | ||
|
|
72d3c513b1 | ||
|
|
ad4b2a0a7c |
@@ -16,19 +16,29 @@ def center_text(text, width):
|
|||||||
def format_gradient_bar(value):
|
def format_gradient_bar(value):
|
||||||
"""
|
"""
|
||||||
Format the gradient bar based on value.
|
Format the gradient bar based on value.
|
||||||
If value is None, show all bars: [|||||||||]
|
If value is None, show all dashes: [---------]
|
||||||
If value is 0-8, replace that position with #: [|#||||||||]
|
If value is 1-9, show the number at its position: [----5----]
|
||||||
"""
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
return "[|||||||||]"
|
return "[---------]"
|
||||||
|
|
||||||
# Ensure value is in valid range
|
# Ensure value is in valid range (1-9)
|
||||||
if not isinstance(value, int) or value < 0 or value > 8:
|
if not isinstance(value, int) or value < 1 or value > 9:
|
||||||
return "[|||||||||]"
|
return "[---------]"
|
||||||
|
|
||||||
bars = list("|||||||||")
|
# Create bar with value at the correct position
|
||||||
bars[value] = "#"
|
bars = [
|
||||||
return "[" + "".join(bars) + "]"
|
"[1--------]", # value 1
|
||||||
|
"[-2-------]", # value 2
|
||||||
|
"[--3------]", # value 3
|
||||||
|
"[---4-----]", # value 4
|
||||||
|
"[----5----]", # value 5
|
||||||
|
"[-----6---]", # value 6
|
||||||
|
"[------7--]", # value 7
|
||||||
|
"[-------8-]", # value 8
|
||||||
|
"[--------9]" # value 9
|
||||||
|
]
|
||||||
|
return bars[value - 1]
|
||||||
|
|
||||||
|
|
||||||
def format_gradient_line(term_left, term_right, value, left_width, right_width, center_width):
|
def format_gradient_line(term_left, term_right, value, left_width, right_width, center_width):
|
||||||
|
|||||||
@@ -33,30 +33,6 @@
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function shareResults() {
|
|
||||||
const json = JSON.stringify(data, null, 2);
|
|
||||||
const file = new File([json], `bicorder-${data.metadata.protocol || 'diagnostic'}.json`, {
|
|
||||||
type: 'application/json',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (navigator.share && navigator.canShare && navigator.canShare({ files: [file] })) {
|
|
||||||
try {
|
|
||||||
await navigator.share({
|
|
||||||
title: 'Protocol Bicorder Diagnostic',
|
|
||||||
text: `Diagnostic for: ${data.metadata.protocol || 'Protocol'}`,
|
|
||||||
files: [file],
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
if ((err as Error).name !== 'AbortError') {
|
|
||||||
console.error('Share failed:', err);
|
|
||||||
alert('Share failed. Try using the Export button instead.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alert('Web Share API not supported. Use the Export button to download the file.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function uploadReadings() {
|
async function uploadReadings() {
|
||||||
isUploading = true;
|
isUploading = true;
|
||||||
|
|
||||||
@@ -128,12 +104,6 @@
|
|||||||
💾 Export JSON
|
💾 Export JSON
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{#if navigator.share}
|
|
||||||
<button on:click={shareResults}>
|
|
||||||
📤 Share
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<button on:click={() => showUploadDialog = !showUploadDialog}>
|
<button on:click={() => showUploadDialog = !showUploadDialog}>
|
||||||
📤 Upload
|
📤 Upload
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -72,23 +72,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderBar(value: number | null): string {
|
function renderBar(value: number | null): string {
|
||||||
// Fixed scale with 9 positions using ||||#||||
|
// Slider-style visualization with brackets and value number
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
return '||||·||||';
|
return '[----X----]';
|
||||||
}
|
}
|
||||||
// Value is 1-9, position the # marker at the right spot
|
// Value is 1-9, show the number at its position along the slider
|
||||||
const positions = [
|
const bars = [
|
||||||
'#||||||||',
|
'[1--------]', // value 1
|
||||||
'|#|||||||',
|
'[-2-------]', // value 2
|
||||||
'||#||||||',
|
'[--3------]', // value 3
|
||||||
'|||#|||||',
|
'[---4-----]', // value 4
|
||||||
'||||#||||',
|
'[----5----]', // value 5 (centered)
|
||||||
'|||||#|||',
|
'[-----6---]', // value 6
|
||||||
'||||||#||',
|
'[------7--]', // value 7
|
||||||
'|||||||#|',
|
'[-------8-]', // value 8
|
||||||
'||||||||#'
|
'[--------9]' // value 9
|
||||||
];
|
];
|
||||||
return positions[value - 1];
|
return bars[value - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
$: barDisplay = renderBar(gradient.value);
|
$: barDisplay = renderBar(gradient.value);
|
||||||
|
|||||||
@@ -42,6 +42,17 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="metadata-field">
|
||||||
|
<label for="description">Description:</label>
|
||||||
|
<textarea
|
||||||
|
id="description"
|
||||||
|
placeholder="[Description]"
|
||||||
|
value={metadata.description || ''}
|
||||||
|
on:input={(e) => handleInput('description', e.currentTarget.value)}
|
||||||
|
rows="3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="metadata-field">
|
<div class="metadata-field">
|
||||||
<label for="analyst">Analyst:</label>
|
<label for="analyst">Analyst:</label>
|
||||||
<input
|
<input
|
||||||
@@ -114,6 +125,15 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
.timestamp-display {
|
.timestamp-display {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export interface AnalysisGradient {
|
|||||||
|
|
||||||
export interface Metadata {
|
export interface Metadata {
|
||||||
protocol: string | null
|
protocol: string | null
|
||||||
|
description: string | null
|
||||||
analyst: string | null
|
analyst: string | null
|
||||||
standpoint: string | null
|
standpoint: string | null
|
||||||
timestamp: string | null
|
timestamp: string | null
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "Protocol Bicorder",
|
"name": "Protocol Bicorder",
|
||||||
"schema": "bicorder.schema.json",
|
"schema": "bicorder.schema.json",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"description": "A diagnostic tool for the study of protocols",
|
"description": "A diagnostic tool for the study of protocols",
|
||||||
"author": "Nathan Schneider",
|
"author": "Nathan Schneider",
|
||||||
"date_modified": "2025-12-02",
|
"date_modified": "2025-12-02",
|
||||||
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"protocol": null,
|
"protocol": null,
|
||||||
|
"description": null,
|
||||||
"analyst": null,
|
"analyst": null,
|
||||||
"standpoint": null,
|
"standpoint": null,
|
||||||
"timestamp": null,
|
"timestamp": null,
|
||||||
"shortform": false
|
"shortform": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"diagnostic": [
|
"diagnostic": [
|
||||||
|
|||||||
Reference in New Issue
Block a user