|
|
import * as d3 from 'd3'; |
|
|
import type { GLTR_Text_Box } from '../vis/GLTR_Text_Box'; |
|
|
import type { Histogram } from '../vis/Histogram'; |
|
|
import type { HistogramBinClickEvent } from '../vis/Histogram'; |
|
|
import type { FrontendAnalyzeResult } from '../api/GLTR_API'; |
|
|
import { calculateHighlights } from '../utils/highlightUtils'; |
|
|
|
|
|
export type HighlightControllerOptions = { |
|
|
stats_frac: Histogram; |
|
|
lmf: GLTR_Text_Box; |
|
|
currentData: { result: FrontendAnalyzeResult } | null; |
|
|
}; |
|
|
|
|
|
export class HighlightController { |
|
|
private options: HighlightControllerOptions; |
|
|
|
|
|
constructor(options: HighlightControllerOptions) { |
|
|
this.options = options; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public clearHighlights(): void { |
|
|
this.options.stats_frac.clearSelection(); |
|
|
this.options.lmf.clearHighlight(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public handleHistogramBinClick(ev: HistogramBinClickEvent): void { |
|
|
const { currentData } = this.options; |
|
|
if (!currentData) return; |
|
|
|
|
|
|
|
|
if (ev.binIndex === -1) { |
|
|
this.clearHighlights(); |
|
|
return; |
|
|
} |
|
|
|
|
|
const { x0, x1, binIndex, no_bins, source } = ev; |
|
|
const data = currentData.result; |
|
|
|
|
|
|
|
|
const { indices, style } = calculateHighlights('token', x0, x1, binIndex, no_bins, data); |
|
|
|
|
|
|
|
|
this.options.lmf.setHighlightedIndices(indices, style); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public updateCurrentData(currentData: { result: FrontendAnalyzeResult } | null): void { |
|
|
|
|
|
(this.options as any).currentData = currentData; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const initHighlightClearListeners = ( |
|
|
clearHighlights: () => void |
|
|
): void => { |
|
|
|
|
|
|
|
|
d3.select('body').on('click.clearHighlight', (event: MouseEvent) => { |
|
|
const target = <HTMLElement>event.target; |
|
|
if (!target) return; |
|
|
|
|
|
|
|
|
const isInteractive = |
|
|
target.closest('.token') || |
|
|
target.closest('button') || |
|
|
target.closest('input') || |
|
|
target.closest('textarea') || |
|
|
target.closest('select') || |
|
|
target.closest('.bar') || |
|
|
target.closest('.hover-area') || |
|
|
target.closest('a') || |
|
|
target.closest('[role="button"]') || |
|
|
target.closest('[onclick]'); |
|
|
|
|
|
|
|
|
if (!isInteractive) { |
|
|
clearHighlights(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
d3.select(window).on('keydown.clearHighlight', (event: KeyboardEvent) => { |
|
|
if (event.key === 'Escape') { |
|
|
clearHighlights(); |
|
|
} |
|
|
}); |
|
|
}; |
|
|
|
|
|
|