<head>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="myDiv" style="width: 800px; height: 500px;">
<!-- Plotly chart will be drawn inside this DIV -->
</div>
<script>
<!-- JAVASCRIPT CODE GOES HERE -->
</script>
</body>
var myPlot = document.getElementById('myDiv'),
x = [1, 2, 3, 4, 5, 6],
y = [1, 2, 3, 2, 3, 4],
colors = ['#00000','#00000','#00000',
'#00000','#00000','#00000'],
data = [{x:x, y:y, type:'scatter',
mode:'markers', marker:{size:16, color:colors}}],
layout = {
yaxis: {
scaleanchor: 'x',
scaleratio: 1,
},
shapes: [{
fillcolor: 'rgba(111, 231, 219, 0.4)',
type: 'path',
path: 'M 1.5 2.5 L 1.5 3.5 L 2.5 3.5 L 2.5 2.5 Z'
}],
hovermode:'closest',
title:'Drag the shape over a point to change its color'
};
Plotly.newPlot('myDiv', data, layout, {editable: true});
var layerAbove = document.getElementsByClassName('layer-above')[0];
layerAbove.addEventListener('mousedown', (event) => { this.onMouseDownHandler(event.target); });
var currentDraggingShape;
this.startDragBehavior();
myPlot.on('plotly_click', function(data){
console.log(data);
var pn='',
tn='',
colors=[];
for(var i=0; i < data.points.length; i++){
pn = data.points[i].pointNumber;
tn = data.points[i].curveNumber;
colors = data.points[i].data.marker.color;
};
colors[pn] = '#C54C82';
var update = {'marker':{color: colors, size:16}};
Plotly.restyle('myDiv', update, [tn]);
});
function checkInsideRect(x0, x1, y0, y1, pX, pY) {
if ((x0 <= pX && x1>= pX) && (y0 <= pY && y1>= pY)) {
return true;
}
return false;
}
function startDragBehavior() {
var drag = Plotly.d3.behavior.drag();
var minX, maxX, minY, maxY, deltaX, deltaY, lastDragPoint;
const graphElement = document.getElementById('myDiv');
drag.on('dragstart', function (e) {
lastDragPoint = getCurrentMousePositionOnCS(event['clientX'], event['clientY'], graphElement);
});
drag.on('drag', function (e) {
if (currentDraggingShape) {
const currentDragPoint = getCurrentMousePositionOnCS(event['clientX'], event['clientY'], graphElement);
deltaX = currentDragPoint.x - lastDragPoint.x;
deltaY = currentDragPoint.y - lastDragPoint.y;
const minX = currentDraggingShape._extremes.x.min[0].val + deltaX;
const maxX = currentDraggingShape._extremes.x.max[0].val + deltaX;
const minY = currentDraggingShape._extremes.y.min[0].val + deltaY;
const maxY = currentDraggingShape._extremes.y.max[0].val + deltaY;
var isInside = false;
for(var i=0; i < graphElement.data[0].x.length; i++){
var pX = graphElement.data[0].x[i];
var pY = graphElement.data[0].y[i];
isInside = checkInsideRect(minX, maxX, minY, maxY, pX, pY);
if (isInside) {
break;
}
};
var colorArray = ['#00000','#00000','#00000', '#00000','#00000','#00000'];
var update;
if (isInside) {
colorArray[i] = 'red';
}
update = {'marker':{color: colorArray, size:16}};
Plotly.restyle('myDiv', update);
}
});
drag.on('dragend', function (e) {
currentDraggingShape = null;
});
Plotly.d3.selectAll('[id=\'' + 'myDiv' + '\']').call(drag);
}
function getCurrentMousePositionOnCS(clientX, clientY, graphElement) {
const clientRect = graphElement.getBoundingClientRect();
const d3X = clientX - clientRect.left;
const d3Y = clientY - clientRect.top;
const left = graphElement._fullLayout.margin.l;
const top = graphElement._fullLayout.margin.t
const currentDragX = graphElement._fullLayout.xaxis.p2c(d3X- left);
const currentDragY = graphElement._fullLayout.yaxis.p2c(d3Y - top);
return {x: currentDragX, y: currentDragY};
}
function onMouseDownHandler(shapeElement) {
const shapeElements = document.getElementsByClassName('layer-above')[0].
getElementsByClassName('shapelayer')[0].getElementsByTagName('path');
let shapeIndex = -1;
for (let i = 0; i < shapeElements.length; i++) {
const shape = shapeElements[i];
if (shape === shapeElement) {
shapeIndex = i;
break;
}
}
currentDraggingShape = document.getElementById('myDiv')._fullLayout.shapes[shapeIndex];
}
This Pen doesn't use any external CSS resources.