Skip to content

Commit 03f5053

Browse files
committed
docs: remove export feature from documentation
1 parent cdc6d62 commit 03f5053

File tree

10 files changed

+47
-206
lines changed

10 files changed

+47
-206
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,18 @@ Contributions welcome! Please follow the project constitution (`.specify/memory/
213213
## 🐛 Troubleshooting
214214

215215
### Plugin tab not showing
216-
- Ensure query type is **CONSTRUCT** (not SELECT/ASK/DESCRIBE)
216+
- Verify plugin is registered correctly
217217
- Check browser console for errors
218218
- Verify YASGUI version is ^4.0.0
219219

220220
### Empty visualization
221-
- Confirm CONSTRUCT query returns triples (check "Table" or "Response" tab)
222-
- Verify results have subject/predicate/object structure
221+
- Ensure query type is **CONSTRUCT** or **DESCRIBE**
222+
- Confirm query returns triples (check "Table" or "Response" tab)
223+
- Verify results have RDF structure
223224

224225
### Performance issues
225226
- Limit results to <1000 nodes for best performance
226-
- Disable physics after initial layout (automatic)
227+
- Disable physics after initial layout
227228
- Consider using LIMIT clause in SPARQL query
228229

229230
For more help, see [Quickstart Guide - Troubleshooting](./specs/001-construct-graph-viz/quickstart.md#troubleshooting).

demo/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ <h2 onclick="toggleInstructions()">
116116
<li><strong>Navigate</strong>: Mouse wheel to zoom, drag background to pan, click "Zoom to Fit" button</li>
117117
<li><strong>Reorganize</strong>: Drag individual nodes to rearrange the layout</li>
118118
<li><strong>Inspect</strong>: Hover over nodes/edges to see full details (300ms delay)</li>
119-
<li><strong>Export</strong>: Click "Export PNG" to save the current viewport as an image</li>
120119
<li><strong>Color coding</strong>: <span style="color: #c5c5c5ff">⬤ Grey</span> = literals,
121120
<span style="color: #e15b13ff">⬤ Orange</span> = blank nodes,
122121
<span style="color: #a6c8a6ff">⬤ Green</span> = rdf:type objects,

specs/001-construct-graph-viz/checklists/requirements.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@
3535

3636
**Clarity Assessment**:
3737
- 5 user stories prioritized (P1-P5) with clear dependencies
38-
- 31 functional requirements organized by category (parsing, rendering, interaction, export, edge cases)
38+
- 31 functional requirements organized by category (parsing, rendering, interaction, edge cases)
3939
- 11 edge cases explicitly handled with defined behaviors
4040
- 8 success criteria all measurable and technology-agnostic
4141
- 8 assumptions documented for context
4242

4343
**No Clarifications Needed**: Specification is complete with informed defaults applied:
4444
- Layout algorithm: Force-directed or hierarchical (standard graph viz approach)
45-
- Export format: PNG/SVG (industry standard image formats)
4645
- Performance target: 2 seconds for 1,000 nodes (aligned with constitution)
4746
- Color scheme: Grey/green/blue with semantic meaning (clear visual hierarchy)
4847
- Label truncation: ~50 chars for literals (reasonable reading length)

specs/001-construct-graph-viz/contracts/vis-network-integration.md

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -374,27 +374,6 @@ network.once('stabilizationIterationsDone', () => {
374374
network.setOptions({physics: {enabled: false}});
375375
});
376376
```
377-
378-
## Export Functionality
379-
380-
```javascript
381-
// Get canvas element
382-
const canvas = network.canvas.frame.canvas;
383-
384-
// Export as PNG
385-
canvas.toBlob(blob => {
386-
const url = URL.createObjectURL(blob);
387-
const link = document.createElement('a');
388-
link.href = url;
389-
link.download = 'graph.png';
390-
link.click();
391-
URL.revokeObjectURL(url);
392-
}, 'image/png');
393-
394-
// Or get data URL
395-
const dataURL = canvas.toDataURL('image/png');
396-
```
397-
398377
## Performance Optimization
399378

400379
### Disable Physics After Layout

specs/001-construct-graph-viz/contracts/yasr-plugin-interface.md

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -233,50 +233,6 @@ getIcon() {
233233
234234
**Side Effects**: None (creates new element each call)
235235
236-
## Optional Methods
237-
238-
### `download(filename)`
239-
240-
**Signature**:
241-
```typescript
242-
download(filename: string): void
243-
```
244-
245-
**Purpose**: Export visualization to file (triggered by YASR download button)
246-
247-
**Contract**:
248-
- Should export visualization in suitable format (PNG, SVG)
249-
- `filename` is suggested name (may need extension)
250-
- Must handle case where visualization not yet rendered
251-
- Optional: YASR shows download button only if method exists
252-
253-
**Example**:
254-
```javascript
255-
download(filename) {
256-
if (!this.network) {
257-
console.warn('No visualization to download');
258-
return;
259-
}
260-
261-
// Export as PNG
262-
const canvas = this.container.querySelector('canvas');
263-
if (canvas) {
264-
canvas.toBlob(blob => {
265-
const url = URL.createObjectURL(blob);
266-
const a = document.createElement('a');
267-
a.href = url;
268-
a.download = `${filename}.png`;
269-
a.click();
270-
URL.revokeObjectURL(url);
271-
});
272-
}
273-
}
274-
```
275-
276-
**Return**: void
277-
278-
**Side Effects**: Triggers browser download
279-
280236
## Data Access Patterns
281237
282238
### Accessing Query Results
@@ -362,14 +318,7 @@ try {
362318
- Create visualization │
363319
- Append to resultsEl │
364320
└─────────────────────────────────────┘
365-
366-
│ User clicks download button
367-
368-
┌─────────────────────────────────────┐
369-
download(filename) │
370-
- Export visualization │
371-
- Trigger browser download │
372-
└─────────────────────────────────────┘
321+
373322
```
374323
375324
## Testing Contract Compliance

specs/001-construct-graph-viz/plan.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
## Summary
99

10-
**Primary Requirement**: Create a YASGUI plugin that visualizes SPARQL CONSTRUCT query results as interactive graphs with nodes (subjects/objects) and edges (predicates), supporting zoom, drag, tooltips, color coding by node type, and PNG image export.
10+
**Primary Requirement**: Create a YASGUI plugin that visualizes SPARQL CONSTRUCT query results as interactive graphs with nodes (subjects/objects) and edges (predicates), supporting zoom, drag, tooltips and color coding by node type.
1111

12-
**Technical Approach**: Implement a YASR plugin class following the yasgui-geo pattern (constructor, canHandleResults, draw, getIcon methods) using vis-network v9.x for graph rendering. Parse RDF triples from bindings format, transform to vis-network DataSets with color-coded nodes (grey literals, green rdf:type objects, blue other URIs), apply prefix abbreviation, and leverage vis-network's built-in force-directed layout, interaction, and export capabilities. Build with esbuild to UMD format for `Yasgui.Yasr.registerPlugin()` registration.
12+
**Technical Approach**: Implement a YASR plugin class following the yasgui-geo pattern (constructor, canHandleResults, draw, getIcon methods) using vis-network v9.x for graph rendering. Parse RDF triples from bindings format, transform to vis-network DataSets with color-coded nodes (grey literals, green rdf:type objects, blue other URIs), apply prefix abbreviation, and leverage vis-network's built-in force-directed layout and interaction. Build with esbuild to UMD format for `Yasgui.Yasr.registerPlugin()` registration.
1313

1414
## Technical Context
1515

specs/001-construct-graph-viz/quickstart.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ LIMIT 100
9797
- **Drag nodes**: Click and drag individual nodes
9898
- **Inspect**: Hover over nodes/edges to see tooltips
9999

100-
### 3. Export Graph
101-
102-
Click the download button (💾) in the YASR toolbar to export the graph as a PNG image.
103-
104100
## Example Queries
105101

106102
### Basic Graph (Entities and Relationships)
@@ -231,7 +227,7 @@ console.log(yasgui.getTab().yasr.results.getBindings());
231227

232228
**Solution**:
233229
1. Limit query results (use `LIMIT 100` or `LIMIT 1000`)
234-
2. Wait for layout stabilization (physics disables automatically)
230+
2. Wait for layout stabilization
235231
3. If still slow, manually disable physics:
236232
```javascript
237233
// In browser console
@@ -309,7 +305,6 @@ See detailed contracts:
309305

310306
- **Issues**: https://github.com/Matdata-eu/yasgui-graph-plugin/issues
311307
- **Discussions**: https://github.com/Matdata-eu/yasgui-graph-plugin/discussions
312-
- **Email**: [email protected]
313308

314309
## License
315310

specs/001-construct-graph-viz/research.md

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
**Decision**: Use **vis-network** for graph visualization with YASR plugin architecture pattern from yasgui-geo example.
1010

1111
**Key Findings**:
12-
- vis-network provides built-in force-directed layout, zoom/pan, drag nodes, and export capabilities
12+
- vis-network provides built-in force-directed layout, zoom/pan and drag nodes capabilities
1313
- YASR plugin pattern requires: constructor, canHandleResults(), draw(), getIcon(), priority, label
1414
- No additional layout libraries needed - vis-network handles all requirements
1515
- Browser compatibility excellent (ES2018+ with Canvas rendering)
@@ -32,7 +32,6 @@
3232
- **Built-in physics engine**: Force-directed and hierarchical layouts out of the box, no additional configuration
3333
- **Interaction model**: Native support for zoom (mouse wheel), pan (drag background), node dragging, tooltips (hover events)
3434
- **Performance**: Handles 1000+ nodes smoothly with physics stabilization optimization
35-
- **Export**: Built-in methods for canvas-to-image conversion (PNG/SVG via canvas API)
3635
- **API simplicity**: `Network(container, data, options)` - single constructor with straightforward data model
3736
- **Browser compatibility**: Canvas-based rendering, works on all modern browsers (Chrome, Firefox, Safari, Edge)
3837
- **Size**: ~500KB minified (~150KB gzipped) - reasonable for functionality provided
@@ -313,34 +312,7 @@ function applyPrefix(uri, prefixes) {
313312
314313
**Decision**: Extract prefixes from YASR query context, apply to all URIs. Include common RDF/RDFS/XSD defaults. Truncate unprefixed URIs with ellipsis.
315314
316-
### 6. Export Image Functionality
317-
318-
**Question**: How to implement "save as image" for current viewport?
319-
320-
**vis-network approach**:
321-
```javascript
322-
// Get canvas element from network
323-
const canvas = network.canvas.frame.canvas;
324-
325-
// Export as PNG
326-
function exportPNG() {
327-
canvas.toBlob(blob => {
328-
const url = URL.createObjectURL(blob);
329-
const a = document.createElement('a');
330-
a.href = url;
331-
a.download = 'graph-visualization.png';
332-
a.click();
333-
URL.revokeObjectURL(url);
334-
});
335-
}
336-
337-
// Export as SVG (requires dom-to-image library or manual SVG creation)
338-
// vis-network doesn't directly support SVG export, PNG is primary format
339-
```
340-
341-
**Decision**: Implement PNG export using canvas.toBlob(). SVG export would require additional library (dom-to-image) - defer to future enhancement, PNG sufficient for success criteria.
342-
343-
### 7. Performance Optimization
315+
### 6. Performance Optimization
344316
345317
**Question**: How to meet <2s rendering target for 1000 nodes?
346318
@@ -373,7 +345,7 @@ const options = {
373345
374346
**Decision**: Use default physics settings with 200 iteration limit. Disable physics after stabilization to improve interaction performance. Monitor performance in testing phase.
375347
376-
### 8. Responsive Layout
348+
### 7. Responsive Layout
377349
378350
**Question**: How to ensure graph fills 100% of YASR container space?
379351
@@ -461,11 +433,7 @@ setTimeout(() => network.fit(), 100);
461433
- Hover tooltips (vis-network hover events + custom overlay)
462434
- Show full URI/literal/datatype
463435
464-
### Phase 5: Export (P5)
465-
- PNG export from canvas
466-
- Download trigger
467-
468-
### Phase 6: Edge Cases & Polish
436+
### Phase 5: Edge Cases & Polish
469437
- Empty state handling
470438
- Self-loop rendering (vis-network supports)
471439
- Label truncation
@@ -477,7 +445,6 @@ setTimeout(() => network.fit(), 100);
477445
None - all critical technical unknowns resolved. Remaining questions are implementation details:
478446
- Exact hex color values (resolved: #808080, #00FF00, #0000FF)
479447
- Tooltip styling (CSS, standard approach)
480-
- Export button placement (within plugin container, consistent with YASR patterns)
481448
- Error messaging for unsupported results (empty state div with message)
482449
483450
## References

specs/001-construct-graph-viz/spec.md

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
**Feature Branch**: `001-construct-graph-viz`
44
**Created**: 2025-12-05
55
**Status**: Draft
6-
**Input**: User description: "Visualize SPARQL CONSTRUCT query results as interactive graphs with nodes (subjects/objects) and edges (predicates), supporting zoom, drag, tooltips, color coding, and image export"
6+
**Input**: User description: "Visualize SPARQL CONSTRUCT query results as interactive graphs with nodes (subjects/objects) and edges (predicates), supporting zoom, drag, tooltips and color coding"
77

88
## Clarifications
99

1010
### Session 2025-12-06
1111

12-
- Q: When a user exports the graph visualization as an image, what should be the exact scope of the export? → A: Export only the visible viewport content at current zoom/pan level (what user currently sees)
1312
- Q: What visual styling should be used for graph nodes to distinguish between different node types and content lengths? → A: All nodes use uniform shape (circle/ellipse) with fixed size, regardless of label length or type
1413
- Q: How should tooltips be triggered and displayed to balance information access with usability? → A: Hover only with 300ms delay before showing, auto-hide on mouse leave
1514
- Q: How should the plugin handle blank nodes (anonymous RDF nodes with no URI) that appear in CONSTRUCT results? → A: Display with generated label but use unique color (e.g., yellow) to distinguish from literals
@@ -84,22 +83,6 @@ While exploring the graph, the user wants to see detailed information about node
8483

8584
---
8685

87-
### User Story 5 - Export Visualization (Priority: P5)
88-
89-
After exploring and potentially adjusting the graph, the user wants to save the current view as an image for documentation, presentations, or reports. They should be able to export exactly what they see in the viewport.
90-
91-
**Why this priority**: Essential for knowledge sharing and documentation, but only valuable after graph is rendered and explored (depends on P1, P2). Lowest priority as core functionality works without it.
92-
93-
**Independent Test**: Render and navigate to a specific view, click export, and verify the downloaded image matches the current viewport appearance.
94-
95-
**Acceptance Scenarios**:
96-
97-
1. **Given** a rendered graph at any zoom/pan level, **When** the user clicks "save as image" control, **Then** the browser downloads a PNG/SVG file showing only the visible viewport content at current zoom/pan (not the entire graph)
98-
2. **Given** a graph with manually repositioned nodes, **When** the user exports the image, **Then** the exported image reflects the current node positions and zoom level exactly as displayed in viewport
99-
3. **Given** a graph is exported, **When** the user opens the image file, **Then** the image has sufficient resolution for readable labels and maintains aspect ratio of the viewport
100-
101-
---
102-
10386
### Edge Cases
10487

10588
- **Empty results**: What happens when a CONSTRUCT query returns zero triples? → Display empty state message "No graph data to visualize"
@@ -163,20 +146,15 @@ After exploring and potentially adjusting the graph, the user wants to save the
163146
- **FR-025**: Plugin MUST display tooltip after 300ms hover delay over edges showing the full prefixed predicate URI
164147
- **FR-026**: Plugin MUST hide tooltips when cursor leaves element boundary (auto-hide on mouse leave)
165148

166-
#### Export
167-
168-
- **FR-027**: Plugin MUST provide "save as image" control that exports only the visible viewport content at current zoom/pan level as a downloadable image file
169-
- **FR-028**: Plugin MUST export image in PNG or SVG format with sufficient resolution for readable labels
170-
171149
#### Edge Case Handling
172150

173-
- **FR-029**: Plugin MUST display empty state message when CONSTRUCT query returns zero triples
174-
- **FR-030**: Plugin MUST handle self-referencing triples (subject equals object) by rendering loop edges
175-
- **FR-031**: Plugin MUST handle blank nodes by creating nodes with generated labels and yellow color
176-
- **FR-032**: Plugin MUST render multiple predicates between the same node pair as separate parallel edges with curved/offset paths
177-
- **FR-033**: Plugin MUST truncate very long URI labels with ellipsis while preserving full URI in tooltips
178-
- **FR-034**: Plugin MUST truncate literal labels exceeding ~50 characters while preserving full value in tooltips
179-
- **FR-035**: Plugin MUST de-duplicate identical triples (same subject, predicate, object) to avoid rendering duplicate edges
151+
- **FR-028**: Plugin MUST display empty state message when CONSTRUCT query returns zero triples
152+
- **FR-029**: Plugin MUST handle self-referencing triples (subject equals object) by rendering loop edges
153+
- **FR-030**: Plugin MUST handle blank nodes by creating nodes with generated labels and yellow color
154+
- **FR-031**: Plugin MUST render multiple predicates between the same node pair as separate parallel edges with curved/offset paths
155+
- **FR-032**: Plugin MUST truncate very long URI labels with ellipsis while preserving full URI in tooltips
156+
- **FR-033**: Plugin MUST truncate literal labels exceeding ~50 characters while preserving full value in tooltips
157+
- **FR-034**: Plugin MUST de-duplicate identical triples (same subject, predicate, object) to avoid rendering duplicate edges
180158

181159
### Key Entities
182160

@@ -203,11 +181,10 @@ After exploring and potentially adjusting the graph, the user wants to save the
203181
- **SC-001**: Users can visualize CONSTRUCT query results as graphs within 2 seconds of receiving results (for graphs up to 1,000 nodes)
204182
- **SC-002**: Users can identify node types (literal vs. blank node vs. URI vs. type instance) through color coding without reading labels (grey/yellow/blue/green)
205183
- **SC-003**: Users can navigate graphs of any size by zooming and panning without performance degradation
206-
- **SC-004**: Users can export publication-ready images of graph visualizations with readable labels
207-
- **SC-005**: Users can reorganize graph layouts manually to improve understanding of relationships
208-
- **SC-006**: Users can access full URI details for any node or edge via hover tooltips
209-
- **SC-007**: Plugin maintains responsive layout across all YASR container sizes (from 320px mobile to 4K desktop)
210-
- **SC-008**: Graph rendering completes successfully for 95% of valid CONSTRUCT query results without errors or empty states (excluding intentionally empty results)
184+
- **SC-004**: Users can reorganize graph layouts manually to improve understanding of relationships
185+
- **SC-005**: Users can access full URI details for any node or edge via hover tooltips
186+
- **SC-006**: Plugin maintains responsive layout across all YASR container sizes (from 320px mobile to 4K desktop)
187+
- **SC-007**: Graph rendering completes successfully for 95% of valid CONSTRUCT query results without errors or empty states (excluding intentionally empty results)
211188

212189
## Assumptions
213190

@@ -218,4 +195,3 @@ After exploring and potentially adjusting the graph, the user wants to save the
218195
- Modern browsers support Canvas or SVG rendering for graph visualization (covered by constitution's browser compatibility requirements)
219196
- Force-directed layout algorithms are acceptable for automatic node positioning (no specific layout algorithm mandated)
220197
- Graph visualizations do not require persistence - each query execution produces a fresh visualization
221-
- Export image resolution is suitable for screen viewing and standard print (no poster-size export required)

0 commit comments

Comments
 (0)