Skip to content

Commit 122dd0b

Browse files
committed
uber wip polar main drag interaction
- selections and hover are working - not much else
1 parent 22cf4ba commit 122dd0b

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

src/plots/polar/constants.js

+3
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ module.exports = {
2525
'lines',
2626
'frontplot'
2727
],
28+
29+
MINDRAG: 8,
30+
MINZOOM: 20,
2831
};

src/plots/polar/polar.js

+195
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@
99
'use strict';
1010

1111
var d3 = require('d3');
12+
var tinycolor = require('tinycolor2');
1213

14+
var Plotly = require('../../plotly');
1315
var Lib = require('../../lib');
1416
var Color = require('../../components/color');
1517
var Drawing = require('../../components/drawing');
1618
var Plots = require('../plots');
1719
var Axes = require('../cartesian/axes');
20+
var dragElement = require('../../components/dragelement');
21+
var dragBox = require('../cartesian/dragbox');
22+
var Fx = require('../../components/fx');
23+
var prepSelect = require('../cartesian/select');
1824

1925
var MID_SHIFT = require('../../constants/alignment').MID_SHIFT;
2026

@@ -23,6 +29,7 @@ var rad2deg = Lib.rad2deg;
2329
var wrap360 = Lib.wrap360;
2430

2531
var constants = require('./constants');
32+
var MINDRAG = constants.MINDRAG;
2633
var axisNames = constants.axisNames;
2734

2835
function Polar(gd, id) {
@@ -36,6 +43,7 @@ function Polar(gd, id) {
3643
this.clipIds = {};
3744

3845
var fullLayout = gd._fullLayout;
46+
var polarLayout = fullLayout[id];
3947
var clipIdBase = 'clip' + fullLayout._uid + id;
4048

4149
this.clipIds.circle = clipIdBase + '-circle';
@@ -45,6 +53,12 @@ function Polar(gd, id) {
4553

4654
this.framework = fullLayout._polarlayer.append('g')
4755
.attr('class', id);
56+
57+
this.viewInitial = {
58+
x: polarLayout.x,
59+
y: polarLayout.y,
60+
zoom: polarLayout.zoom
61+
};
4862
}
4963

5064
var proto = Polar.prototype;
@@ -435,6 +449,187 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
435449
.call(Color.stroke, angularLayout.linecolor);
436450
};
437451

452+
proto.updateFx = function(fullLayout, polarLayout) {
453+
if(!this.gd._context.staticPlot) {
454+
this.updateMainDrag(fullLayout, polarLayout);
455+
}
456+
};
457+
458+
proto.updateMainDrag = function(fullLayout) {
459+
var _this = this;
460+
var gd = _this.gd;
461+
var layers = _this.layers;
462+
var zoomlayer = fullLayout._zoomlayer;
463+
464+
var mainDrag = dragBox.makeDragger(
465+
layers, 'maindrag', 'crosshair',
466+
_this.xOffset2, _this.yOffset2, _this.xLength2, _this.yLength2
467+
);
468+
469+
var dragOpts = {
470+
element: mainDrag,
471+
gd: gd,
472+
subplot: _this.id,
473+
plotinfo: {
474+
xaxis: _this.xaxis,
475+
yaxis: _this.yaxis
476+
},
477+
xaxes: [_this.xaxis],
478+
yaxes: [_this.yaxis]
479+
};
480+
481+
// use layout domain and offsets to shadow full subplot domain on 'zoom'
482+
var pw = _this.xLength;
483+
var ph = _this.yLength;
484+
var xs = _this.xOffset;
485+
var ys = _this.yOffset;
486+
var x0, y0;
487+
var box, path0, dimmed, lum;
488+
var zb, corners;
489+
490+
function zoomPrep(evt, startX, startY) {
491+
var bbox = mainDrag.getBoundingClientRect();
492+
var polarLayoutNow = gd._fullLayout[_this.id];
493+
x0 = startX - bbox.left;
494+
y0 = startY - bbox.top;
495+
box = {l: x0, r: x0, w: 0, t: y0, b: y0, h: 0};
496+
lum = tinycolor(polarLayoutNow.bgcolor).getLuminance();
497+
path0 = 'M0,0H' + pw + 'V' + ph + 'H0V0';
498+
dimmed = false;
499+
500+
zb = dragBox.makeZoombox(zoomlayer, lum, xs, ys, path0);
501+
corners = dragBox.makeCorners(zoomlayer, xs, ys);
502+
dragBox.clearSelect(zoomlayer);
503+
}
504+
505+
function zoomMove(dx0, dy0) {
506+
var x1 = Math.max(0, Math.min(pw, dx0 + x0));
507+
var y1 = Math.max(0, Math.min(ph, dy0 + y0));
508+
var dx = Math.abs(x1 - x0);
509+
var dy = Math.abs(y1 - y0);
510+
511+
box.w = box.h = Math.max(dx, dy);
512+
var delta = box.w / 2;
513+
514+
if(dx > dy) {
515+
box.l = Math.min(x0, x1);
516+
box.r = Math.max(x0, x1);
517+
box.t = Math.min(y0, y1) - delta;
518+
box.b = Math.min(y0, y1) + delta;
519+
} else {
520+
box.t = Math.min(y0, y1);
521+
box.b = Math.max(y0, y1);
522+
box.l = Math.min(x0, x1) - delta;
523+
box.r = Math.max(x0, x1) + delta;
524+
}
525+
526+
dragBox.updateZoombox(zb, corners, box, path0, dimmed, lum);
527+
corners.attr('d', dragBox.xyCorners(box));
528+
dimmed = true;
529+
}
530+
531+
function zoomDone(dragged, numClicks) {
532+
if(Math.min(box.h, box.w) < MINDRAG * 2) {
533+
if(numClicks === 2) doubleClick();
534+
return dragBox.removeZoombox(gd);
535+
}
536+
537+
dragBox.removeZoombox(gd);
538+
539+
// var updateObj = {};
540+
// var polarUpdateObj = updateObj[_this.id] = {};
541+
// Plotly.relayout(gd, polarUpdateObj);
542+
}
543+
544+
function panMove(dx, dy) {
545+
var vb = [dx, dy, pw - dx, ph - dy];
546+
updateByViewBox(vb);
547+
}
548+
549+
function panDone(dragged, numClicks) {
550+
if(dragged) {
551+
updateByViewBox([0, 0, pw, ph]);
552+
} else if(numClicks === 2) {
553+
doubleClick();
554+
}
555+
}
556+
557+
function zoomWheel() {
558+
// TODO
559+
}
560+
561+
function updateByViewBox(vb) {
562+
var ax = _this.xaxis;
563+
var xScaleFactor = vb[2] / ax._length;
564+
var yScaleFactor = vb[3] / ax._length;
565+
var clipDx = vb[0];
566+
var clipDy = vb[1];
567+
568+
var plotDx = ax._offset - clipDx / xScaleFactor;
569+
var plotDy = ax._offset - clipDy / yScaleFactor;
570+
571+
_this.framework
572+
.call(Drawing.setTranslate, -plotDx, -plotDy);
573+
// .call(Drawing.setScale, 1 / xScaleFactor, 1 / yScaleFactor);
574+
575+
// maybe cache this at the plot step
576+
var traceGroups = _this.framework.selectAll('.trace');
577+
578+
traceGroups.selectAll('.point')
579+
.call(Drawing.setPointGroupScale, xScaleFactor, yScaleFactor);
580+
traceGroups.selectAll('.textpoint')
581+
.call(Drawing.setTextPointsScale, xScaleFactor, yScaleFactor);
582+
traceGroups
583+
.call(Drawing.hideOutsideRangePoints, _this);
584+
}
585+
586+
function doubleClick() {
587+
gd.emit('plotly_doubleclick', null);
588+
// Plotly.relayout(gd, Lib.extendFlat({}, _this.viewInitial));
589+
}
590+
591+
dragOpts.prepFn = function(evt, startX, startY) {
592+
var dragModeNow = gd._fullLayout.dragmode;
593+
594+
switch(dragModeNow) {
595+
case 'zoom':
596+
dragOpts.moveFn = zoomMove;
597+
dragOpts.doneFn = zoomDone;
598+
zoomPrep(evt, startX, startY);
599+
break;
600+
case 'pan':
601+
dragOpts.moveFn = panMove;
602+
dragOpts.doneFn = panDone;
603+
break;
604+
case 'select':
605+
case 'lasso':
606+
prepSelect(evt, startX, startY, dragOpts, dragModeNow);
607+
break;
608+
}
609+
};
610+
611+
mainDrag.onmousemove = function(evt) {
612+
Fx.hover(gd, evt, _this.id);
613+
gd._fullLayout._lasthover = mainDrag;
614+
gd._fullLayout._hoversubplot = _this.id;
615+
};
616+
617+
mainDrag.onmouseout = function(evt) {
618+
if(gd._dragging) return;
619+
dragElement.unhover(gd, evt);
620+
};
621+
622+
mainDrag.onclick = function(evt) {
623+
Fx.click(gd, evt, _this.id);
624+
};
625+
626+
if(gd._context.scaleZoom) {
627+
dragBox.attachWheelEventHandler(mainDrag, zoomWheel);
628+
}
629+
630+
dragElement.init(dragOpts);
631+
};
632+
438633
proto.isPtWithinSector = function() {
439634
var sector = this.sector;
440635

0 commit comments

Comments
 (0)