it('global mouse position broadcasting', (done) => { [div, api] = createElementAndApi( simple1dHorizontalVerticalAnd2dDataTrack, { editable: false, bounded: true } ); api.setBroadcastMousePositionGlobally(true); let mouseMoveEvt = null; globalPubSub.subscribe('higlass.mouseMove', (evt) => { mouseMoveEvt = evt; }); const createMouseEvent = (type, x, y) => new MouseEvent(type, { view: window, bubbles: true, cancelable: true, // WARNING: The following property is absolutely crucial to have the // event being picked up by PIXI. Do not remove under any circumstances! // pointerType: 'mouse', screenX: x, screenY: y, clientX: x, clientY: y }); waitForTilesLoaded(api.getComponent(), () => { const tiledPlotDiv = div.querySelector('.tiled-plot-div'); tiledPlotDiv.dispatchEvent(createMouseEvent('mousemove', 150, 150)); setTimeout(() => { expect(mouseMoveEvt).not.toEqual(null); expect(mouseMoveEvt.x).toEqual(150); expect(mouseMoveEvt.y).toEqual(150); expect(mouseMoveEvt.relTrackX).toEqual(85); expect(mouseMoveEvt.relTrackY).toEqual(85); expect(Math.round(mouseMoveEvt.dataX)).toEqual(1670179850); expect(Math.round(mouseMoveEvt.dataY)).toEqual(1832488682); expect(mouseMoveEvt.isFrom2dTrack).toEqual(true); expect(mouseMoveEvt.isFromVerticalTrack).toEqual(false); expect(mouseMoveEvt.sourceUid).toBeDefined(); expect(mouseMoveEvt.noHoveredTracks).toEqual(false); mouseMoveEvt = null; api.setBroadcastMousePositionGlobally(false); tiledPlotDiv.dispatchEvent(createMouseEvent('mousemove', 150, 150)); setTimeout(() => { expect(mouseMoveEvt).toEqual(null); done(); }, 0); }, 0); }); });
const showMousePosition = ( pubSub, pubSubs, options, getScales, getPosition, getDimensions, getIsFlipped, is2d, isGlobal ) => { pubSub.publish('app.animateOnMouseMove', true); const color = options.mousePositionColor ? hexStrToInt(options.mousePositionColor) : COLOR; const alpha = options.mousePositionAlpha || ALPHA; // Graphics for cursor position const graphics = new PIXI.Graphics(); // This clears the mouse position graphics, i.e., the mouse position will not // be visible afterwards. const clearGraphics = () => { graphics.clear(); }; /** * Draw 1D mouse location (cross) hair onto the PIXI graphics. * * @param {Integer} mousePos One dimension of the mouse location * @param {Boolean} isHorizontal If `true` the dimension to be drawn is * horizontal. * @param {Boolean} isNoClear If `true` do not clear the graphics. */ const drawMousePosition = (mousePos, isHorizontal, isNoClear) => { if (!isNoClear) clearGraphics(); graphics.lineStyle(1, color, alpha); if (isHorizontal) { const addition = is2d ? getPosition()[0] : 0; graphics.moveTo(0, mousePos); graphics.lineTo(getDimensions()[0] + addition, mousePos); } else { const addition = is2d ? getPosition()[1] : 0; graphics.moveTo(mousePos, 0); graphics.lineTo(mousePos, getDimensions()[1] + addition); } }; /** * Mouse move handler * * @param {Object} e Event object. */ const mouseMoveHandler = (event) => { if (event.noHoveredTracks) { clearGraphics(); return graphics; } let x; let y; if (event.isFromVerticalTrack) { x = event.dataY; y = event.dataY; } else { x = event.dataX; y = event.isFrom2dTrack ? event.dataY : event.dataX; } // 2d or central tracks are not offset and rather rely on a mask, i.e., the // top left *visible* position is *not* [0,0] but given by `getPosition()`. const offset = is2d ? getPosition() : [0, 0]; // `getIsFlipped()` is `true` when a horizontal track has been flipped by 90 // degree, i.e., is a vertical track. const mousePos = getIsFlipped() ? getScales()[0](y) + offset[1] : getScales()[0](x) + offset[0]; drawMousePosition(mousePos); // Also draw the second dimension if (is2d) drawMousePosition(getScales()[1](y) + offset[1], true, true); return graphics; }; pubSubs.push(pubSub.subscribe('app.mouseMove', mouseMoveHandler)); pubSubs.push(pubSub.subscribe('app.mouseLeave', clearGraphics)); pubSubs.push(pubSub.subscribe('blur', clearGraphics)); if (isGlobal) { pubSubs.push(globalPubSub.subscribe('higlass.mouseMove', mouseMoveHandler)); } return graphics; };