fix: Preserve 3D plot camera and improve documentation
This commit addresses PR feedback and fixes plot camera behavior. ## JavaScript Fix - Camera Preservation - Changed plot update strategy from recreating layout to using Plotly.restyle() - Query point visibility now toggles via restyle() which only modifies trace visibility - Camera position/zoom naturally preserved since layout remains untouched - Resolves jumpy plot behavior when toggling "Show Query Point" checkbox Related: nextcloud_mcp_server/auth/static/vector-viz.js:58-73 ## Documentation Improvements - Condensed vector-sync-ui.md from 316 to 94 lines (~70% reduction) - Removed redundant FAQ section (content merged into main sections) - Simplified use cases from 4 detailed sections to 3 focused paragraphs - Streamlined troubleshooting to 3 common issues - Merged technical details into overview section - Retained all essential information while improving readability ## Screenshot Updates Removed old/outdated images (5 files): - rag-workflow-bidirectional-final.png - rag-workflow-prominent-llm.png - rag-workflow-simple-final.png - vector-viz-interface.png - welcome-page.png Replaced with current screenshots (3 files): - vector-viz-document-types-2col.png - Now shows plot + results - vector-viz-chunk-context.png - Centered content view - vector-viz-results.png - Updated results list 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -56,16 +56,26 @@ function vizApp() {
|
||||
},
|
||||
|
||||
updatePlot() {
|
||||
// Re-render plot with current data when toggle changes
|
||||
// Toggle query point visibility without recreating the plot
|
||||
// This preserves camera position naturally since layout is untouched
|
||||
if (this.coordinates && this.queryCoords && this.results.length > 0) {
|
||||
this.renderPlot(this.coordinates, this.queryCoords, this.results);
|
||||
const plotDiv = document.getElementById('viz-plot');
|
||||
|
||||
// If plot exists, just toggle the query trace visibility
|
||||
if (plotDiv && plotDiv.data && plotDiv.data.length >= 2) {
|
||||
// Trace index 1 is the query point
|
||||
Plotly.restyle('viz-plot', { visible: this.showQueryPoint }, [1]);
|
||||
} else {
|
||||
// Plot doesn't exist yet, render it
|
||||
this.renderPlot(this.coordinates, this.queryCoords, this.results);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
renderPlot(coordinates, queryCoords, results) {
|
||||
const scores = results.map(r => r.score);
|
||||
|
||||
// Trace 1: Document results
|
||||
// Trace 1: Document results (always visible)
|
||||
const documentTrace = {
|
||||
x: coordinates.map(c => c[0]),
|
||||
y: coordinates.map(c => c[1]),
|
||||
@@ -73,6 +83,7 @@ function vizApp() {
|
||||
mode: 'markers',
|
||||
type: 'scatter3d',
|
||||
name: 'Documents',
|
||||
visible: true,
|
||||
customdata: results.map((r, i) => ({
|
||||
title: r.title,
|
||||
raw_score: r.original_score,
|
||||
@@ -98,7 +109,7 @@ function vizApp() {
|
||||
}
|
||||
};
|
||||
|
||||
// Trace 2: Query point (distinct marker)
|
||||
// Trace 2: Query point (visibility controlled by toggle)
|
||||
const queryTrace = {
|
||||
x: [queryCoords[0]],
|
||||
y: [queryCoords[1]],
|
||||
@@ -106,6 +117,7 @@ function vizApp() {
|
||||
mode: 'markers',
|
||||
type: 'scatter3d',
|
||||
name: 'Query',
|
||||
visible: this.showQueryPoint, // Initial visibility from state
|
||||
hovertemplate:
|
||||
'<b>Search Query</b><br>' +
|
||||
`(x=${queryCoords[0]}, y=${queryCoords[1]}, z=${queryCoords[2]})` +
|
||||
@@ -120,22 +132,15 @@ function vizApp() {
|
||||
}
|
||||
};
|
||||
|
||||
// Preserve camera position if plot already exists
|
||||
const plotDiv = document.getElementById('viz-plot');
|
||||
let cameraSettings = { eye: { x: 1.5, y: 1.5, z: 1.5 } }; // Default camera position
|
||||
|
||||
if (plotDiv && plotDiv.layout && plotDiv.layout.scene && plotDiv.layout.scene.camera) {
|
||||
// Plot exists and has been interacted with - preserve current camera
|
||||
cameraSettings = plotDiv.layout.scene.camera;
|
||||
}
|
||||
|
||||
const layout = {
|
||||
title: `Vector Space (PCA 3D) - ${results.length} results`,
|
||||
scene: {
|
||||
xaxis: { title: 'PC1' },
|
||||
yaxis: { title: 'PC2' },
|
||||
zaxis: { title: 'PC3' },
|
||||
camera: cameraSettings
|
||||
camera: {
|
||||
eye: { x: 1.5, y: 1.5, z: 1.5 }
|
||||
}
|
||||
},
|
||||
hovermode: 'closest',
|
||||
autosize: true, // Enable auto-sizing to fit container
|
||||
@@ -143,8 +148,8 @@ function vizApp() {
|
||||
margin: { l: 0, r: 0, t: 40, b: 0 } // Minimize margins for full width
|
||||
};
|
||||
|
||||
// Conditionally include query trace based on toggle
|
||||
const traces = this.showQueryPoint ? [documentTrace, queryTrace] : [documentTrace];
|
||||
// Always render both traces - visibility is controlled by the visible property
|
||||
const traces = [documentTrace, queryTrace];
|
||||
|
||||
// Enable responsive resizing
|
||||
const config = {
|
||||
@@ -152,9 +157,9 @@ function vizApp() {
|
||||
displayModeBar: true
|
||||
};
|
||||
|
||||
// Use Plotly.react() instead of newPlot() to preserve camera position
|
||||
// when toggling query point visibility
|
||||
Plotly.react('viz-plot', traces, layout, config);
|
||||
// Use newPlot() for initial render - camera position will be preserved
|
||||
// by subsequent Plotly.restyle() calls in updatePlot()
|
||||
Plotly.newPlot('viz-plot', traces, layout, config);
|
||||
},
|
||||
|
||||
getNextcloudUrl(result) {
|
||||
|
||||
Reference in New Issue
Block a user