I’ve been trying to create a plot where the user can choose to zoom, select an area of the plot of which can make a selection, or some combination of zooming and selecting. I’m encountering a few problems
- There are problems appearing in a few places. Let me try to list them:
- If you try zooming and then pressing addSelection then you get a plot of the zoomed image
- Now double click the plot to zoom out. You’ll see the original plot
- When you zoom out of the original plot, the name changes. I’m not sure why
- If you zoom and then Begin Selection, you can select the desired points on the plot and export that to a new graph
- When you try to zoom back out on the original plot, you don’t get the original plot.
- If you just use Begin Selection without zooming, then you get the section of the plot you want
- However, the original plot’s name changes
- Zoom in, Press Begin Selection, select some content, press End Selection, and attempt to zoom out. Instead of seeing the whole plot, you zoom into the previously selected content.
I’m willing to attribute these bugs to not having a thorough understanding of how relayout works (or another Plotly.js feature). However, if anyone could offer an explanation of why these bugs appear or a suggestion on where to go, I would be immensly grateful.
Here is some reproducible code:
<body>
<div>
<button onclick="downloadMainPlot()">Download</button>
<button onclick="beginSelecting()">Begin Selecting</button>
<button onclick="endSelecting()">End Selecting</button>
<button onclick="addSelection()">Add Selection</button>
</div>
<div id="graph">
<!-- Plotly chart will be drawn inside this DIV -->
</div>
<div id="selectedPlots">
<!-- All confirmed selections will be drawn inside this DIV -->
</div>
<script>
var graphDiv = document.getElementById('graph');
var MAX_POINTS = 100;
const layout = {
dragmode: 'zoom',
title: 'Random Increase',
xaxis: {
},
yaxis: {
},
legend: true
};
var x = [];
var y = [];
for (var i = 0; i < MAX_POINTS; i++) {
x.push(i);
y.push(i / (Math.cos(i) + 2) + Math.sin(i));
}
const trace1 = {
name: 1,
x: x,
y: x,
type: 'scatter',
mode: 'lines+markers',
marker: {
opacity: 0,
},
line: {
color: 'rgb(82, 64, 219)',
}
};
const trace2 = {
name: 2,
x: x,
y: y,
type: 'scatter',
mode: 'lines+markers',
marker: {
opacity: 0,
},
line: {
color: 'rgb(219, 64, 82)',
}
};
var data = [trace1, trace2];
Plotly.newPlot(graphDiv, data, layout, { displayModeBar: false });
var selectCount = 0;
var traceNew1 = trace1,
traceNew2 = trace2;
graphDiv.on('plotly_selected', function (eventData) {
traceNew1.x = [];
traceNew1.y = [];
traceNew2.x = [];
traceNew2.y = [];
if (eventData) {
if (eventData.points) {
eventData.points.forEach(function (pt) {
if (pt.data.name == 1) {
traceNew1.y.push(pt.y);
traceNew1.x.push(pt.x);
} else if (pt.data.name == 2) {
traceNew2.y.push(pt.y);
traceNew2.x.push(pt.x);
}
});
}
}
});
function addSelection() {
var newSelect = document.createElement('DIV');
var newID = 'plot' + selectCount.toString();
newSelect.setAttribute("id", newID);
console.log('new DIV', newSelect);
// Display new Plot before old
if (!selectCount) {
document.getElementById('selectedPlots').appendChild(newSelect);
} else {
document.getElementById('selectedPlots').insertBefore(newSelect, document.getElementById('selectedPlots').firstChild)
}
var update = {
title: "New Plot #" + selectCount.toString(),
dragmode: 'zoom',
};
Plotly.newPlot(
document.getElementById(newID),
[traceNew1, traceNew2],
layout,
{
displayModeBar: false
}
);
Plotly.relayout(document.getElementById(newID), update);
newSelect = null;
selectCount++;
}
function beginSelecting() {
console.log('beginSelecting Activated');
Plotly.relayout(graphDiv, { dragmode: 'select' });
}
function endSelecting() {
console.log('endSelecting Activated');
Plotly.relayout(graphDiv, { dragmode: 'zoom' });
}
function downloadMainPlot() {
Plotly.downloadImage(graphDiv, { format: 'png', width: 800, height: 600, filename: 'newplot' });
}
graphDiv.on('plotly_relayout', function (ed) {
console.log('Plotly_relayout ', ed);
});
</script>
</body>