github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/components/TimelineChart/CrosshairSync.plugin.ts (about) 1 const defaultOptions = { 2 syncCrosshairsWith: [], 3 }; 4 5 // Enhances the default Plot object with the API from the crosshair plugin 6 // https://github.com/flot/flot/blob/de34ce947d8ebfb2cac0b682a130ba079d8d654b/source/jquery.flot.crosshair.js#L74 7 type PlotWithCrosshairsSupport = jquery.flot.plot & 8 jquery.flot.plotOptions & { 9 setCrosshair(pos: { x: number; y: number }): void; 10 clearCrosshair(): void; 11 }; 12 13 (function ($) { 14 function init(plot: PlotWithCrosshairsSupport) { 15 function getOptions() { 16 return plot.getOptions() as jquery.flot.plotOptions & { 17 syncCrosshairsWith: typeof defaultOptions['syncCrosshairsWith']; 18 }; 19 } 20 21 function accessExternalInstance(id: string) { 22 // Access another flotjs instance 23 // https://github.com/flot/flot/blob/de34ce947d8ebfb2cac0b682a130ba079d8d654b/source/jquery.flot.js#L969 24 const p: PlotWithCrosshairsSupport = $(`#${id}`).data('plot'); 25 return p; 26 } 27 28 function onPlotHover( 29 syncCrosshairsWith: typeof defaultOptions['syncCrosshairsWith'], 30 e: unknown, 31 position: { x: number; y: number } 32 ) { 33 syncCrosshairsWith.forEach((id) => 34 accessExternalInstance(id).setCrosshair(position) 35 ); 36 } 37 38 function clearCrosshairs( 39 syncCrosshairsWith: typeof defaultOptions['syncCrosshairsWith'] 40 ) { 41 syncCrosshairsWith.forEach((id) => 42 accessExternalInstance(id).clearCrosshair() 43 ); 44 } 45 46 plot.hooks!.bindEvents!.push(() => { 47 const options = getOptions(); 48 49 plot 50 .getPlaceholder() 51 .bind('plothover', onPlotHover.bind(null, options.syncCrosshairsWith)); 52 53 plot 54 .getPlaceholder() 55 .bind( 56 'mouseleave', 57 clearCrosshairs.bind(null, options.syncCrosshairsWith) 58 ); 59 }); 60 61 plot.hooks!.shutdown!.push(() => { 62 const options = getOptions(); 63 64 clearCrosshairs(options.syncCrosshairsWith); 65 66 plot 67 .getPlaceholder() 68 .bind( 69 'mouseleave', 70 clearCrosshairs.bind(null, options.syncCrosshairsWith) 71 ); 72 73 plot 74 .getPlaceholder() 75 .unbind( 76 'plothover', 77 onPlotHover.bind(null, options.syncCrosshairsWith) 78 ); 79 }); 80 } 81 82 $.plot.plugins.push({ 83 init, 84 options: defaultOptions, 85 name: 'crosshair-sync', 86 version: '1.0', 87 }); 88 })(jQuery);