Skip to content

Commit 19957db

Browse files
author
Nikita Stepochkin
committed
feat: resizable box
1 parent 98c92ed commit 19957db

File tree

1 file changed

+88
-52
lines changed

1 file changed

+88
-52
lines changed

index.html

Lines changed: 88 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,38 @@
1515
overflow: hidden;
1616
font-family: Arial, sans-serif;
1717
}
18+
1819
#sidebar {
1920
width: 300px;
2021
padding: 15px;
2122
background-color: #f8f9fa;
2223
overflow-y: auto;
2324
flex-shrink: 0;
2425
}
25-
#div-plotly {
26-
flex-grow: 1;
27-
padding: 15px;
28-
overflow: auto;
29-
min-width: 200px;
30-
min-height: 300px;
26+
27+
.box {
28+
width: 300px;
29+
height: 200px;
30+
background-color: #fff;
31+
border: 1px solid dodgerblue;
32+
border-radius: 5px;
33+
box-shadow: 0 15px 15px lightgrey;
3134
}
32-
.resizer {
33-
width: 10px;
34-
background: #ddd;
35-
cursor: ew-resize;
36-
position: relative;
37-
z-index: 1;
35+
36+
.box-header {
37+
color: #fff;
38+
background-color: dodgerblue;
39+
padding: 10px 15px;
3840
}
39-
.resizer:hover {
40-
background: #bbb;
41+
42+
.drag-handle {
43+
cursor: pointer;
44+
}
45+
46+
.box-header {
47+
color: #fff;
48+
background-color: dodgerblue;
49+
padding: 5px 10px;
4150
}
4251
</style>
4352
</head>
@@ -52,10 +61,14 @@ <h1>Plotly JSON Visualizer</h1>
5261
<button onclick="reloadPlot()" class="btn btn-success">Reload Plot</button>
5362
</div>
5463
</div>
55-
<div class="resizer" id="left-resizer"></div>
56-
<div id="div-plotly"></div>
64+
<div class="box" data-draggable="true" data-resizable="true">
65+
<div class="box-header drag-handle" data-drag-handle="true">Drag here</div>
66+
<div class="box-body" id="div-plotly"></div>
67+
</div>
5768

5869
<script>
70+
const plotDiv = document.getElementById('div-plotly');
71+
5972
function reloadPlot() {
6073
const jsonData = document.getElementById('json-input').value;
6174
const jsonPath = document.getElementById('json-path').value;
@@ -70,57 +83,80 @@ <h1>Plotly JSON Visualizer</h1>
7083
}
7184
}
7285

73-
Plotly.newPlot(document.getElementById('div-plotly'), plotData);
86+
var layout = {
87+
title: 'Responsive Plotly.js Chart',
88+
autosize: true
89+
};
90+
91+
var config = {
92+
responsive: true
93+
};
94+
95+
Plotly.newPlot(plotDiv, plotData, layout, config);
7496
} catch (error) {
7597
console.error('Error:', error);
7698
alert('Invalid JSON data or JSON path');
7799
}
78100
}
79101

80-
// Event listener to redraw the plot when the div is resized
81-
const resizeObserver = new ResizeObserver(() => {
82-
const jsonData = document.getElementById('json-input').value;
83-
if (jsonData.trim() !== "") {
84-
reloadPlot();
85-
}
86-
});
87-
88-
resizeObserver.observe(document.getElementById('div-plotly'));
102+
let dragEl;
103+
let dragHandleEl
104+
const lastPosition = {};
89105

90-
// Functionality for dragging resizers
91-
const leftResizer = document.getElementById('left-resizer');
92-
const sidebar = document.getElementById('sidebar');
93-
const plotlyContainer = document.getElementById('div-plotly');
106+
setupResizable();
107+
setupDraggable();
94108

95-
function initResizer(resizer, sidePanel) {
96-
let x = 0;
97-
let w = 0;
109+
function setupDraggable() {
110+
dragHandleEl = document.querySelector('[data-drag-handle]');
111+
dragHandleEl.addEventListener('mousedown', dragStart);
112+
dragHandleEl.addEventListener('mouseup', dragEnd);
113+
dragHandleEl.addEventListener('mouseout', dragEnd);
114+
}
98115

99-
const mouseDownHandler = function(e) {
100-
x = e.clientX;
101-
w = sidePanel.offsetWidth;
116+
function setupResizable() {
117+
const resizeEl = document.querySelector('[data-resizable]');
118+
resizeEl.style.setProperty('resize', 'both');
119+
resizeEl.style.setProperty('overflow', 'hidden');
120+
new ResizeObserver(() => {
121+
updatePlotSize();
122+
}).observe(resizeEl);
123+
}
102124

103-
document.addEventListener('mousemove', mouseMoveHandler);
104-
document.addEventListener('mouseup', mouseUpHandler);
105-
};
125+
function dragStart(event) {
126+
dragEl = getDraggableAncestor(event.target);
127+
dragEl.style.setProperty('position', 'absolute');
128+
lastPosition.left = event.target.clientX;
129+
lastPosition.top = event.target.clientY;
130+
dragHandleEl.classList.add('dragging');
131+
dragHandleEl.addEventListener('mousemove', dragMove);
132+
}
106133

107-
const mouseMoveHandler = function(e) {
108-
const dx = e.clientX - x;
109-
const newWidth = w + dx;
110-
if (newWidth >= 200 && newWidth <= window.innerWidth - 300) { // Adjust min and max width as needed
111-
sidePanel.style.width = `${newWidth}px`;
112-
}
113-
};
134+
function dragMove(event) {
135+
const dragElRect = dragEl.getBoundingClientRect();
136+
const newLeft = dragElRect.left + event.clientX - lastPosition.left;
137+
const newTop = dragElRect.top + event.clientY - lastPosition.top;
138+
dragEl.style.setProperty('left', `${newLeft}px`);
139+
dragEl.style.setProperty('top', `${newTop}px`);
140+
lastPosition.left = event.clientX;
141+
lastPosition.top = event.clientY;
142+
window.getSelection().removeAllRanges();
143+
updatePlotSize();
144+
}
114145

115-
const mouseUpHandler = function() {
116-
document.removeEventListener('mousemove', mouseMoveHandler);
117-
document.removeEventListener('mouseup', mouseUpHandler);
118-
};
146+
function updatePlotSize() {
147+
Plotly.Plots.resize(plotDiv);
148+
}
119149

120-
resizer.addEventListener('mousedown', mouseDownHandler);
150+
function getDraggableAncestor(element) {
151+
if (element.getAttribute('data-draggable')) return element;
152+
return getDraggableAncestor(element.parentElement);
121153
}
122154

123-
initResizer(leftResizer, sidebar);
155+
function dragEnd() {
156+
dragHandleEl.classList.remove('dragging');
157+
dragHandleEl.removeEventListener('mousemove', dragMove);
158+
dragEl = null;
159+
}
124160
</script>
125161
</body>
126162
</html>

0 commit comments

Comments
 (0)