import * as d3 from "d3" ; import * as _ from "lodash" ; type Selection < T1 , T2 = T1 > = d3 . Selection < any , T1 , any , T2 > ; import { interactivityBaseService as interactivityService } from "powerbi-visuals-utils-interactivityutils" ; import IInteractiveBehavior = interactivityService . IInteractiveBehavior ; import IInteractivityService = interactivityService . IInteractivityService ; import ISelectionHandler = interactivityService . ISelectionHandler ; import { Task , GroupedTask } from "./interfaces" ; import { IBehaviorOptions } from "powerbi-visuals-utils-interactivityutils/lib/interactivityBaseService" ; export const DimmedOpacity = 0.4 ; export const DefaultOpacity = 1.0 ; const getEvent = ( ) => require ( "d3-selection" ) . event ; export function getFillOpacity ( selected , highlight , hasSelection , hasPartialHighlights ) { if ( ( hasPartialHighlights && ! highlight ) || ( hasSelection && ! selected ) ) { return DimmedOpacity ; } return DefaultOpacity ; } export interface BehaviorOptions extends IBehaviorOptions < Task > { clearCatcher : Selection < any > ; taskSelection : Selection < Task > ; legendSelection : Selection < any > ; interactivityService : IInteractivityService < Task > ; subTasksCollapse : { selection : Selection < any > ; callback : ( groupedTask : GroupedTask ) => void ; } ; allSubtasksCollapse : { selection : Selection < any > ; callback : ( ) => void ; } ; } export class Behavior implements IInteractiveBehavior { private options : BehaviorOptions ; public bindEvents ( options , selectionHandler ) { this . options = options ; let clearCatcher = options . clearCatcher ; options . taskSelection . on ( "click" , ( dataPoint ) => { const event = d3 . event as MouseEvent ; selectionHandler . handleSelection ( dataPoint , event . ctrlKey ) ; event . stopPropagation ( ) ; } ) ; options . legendSelection . on ( "click" , ( d ) => { if ( ! d . selected ) { selectionHandler . handleSelection ( d , getEvent ( ) . ctrlKey ) ; ( d3 . event as MouseEvent ) . stopPropagation ( ) ; let selectedType = d . tooltip ; options . taskSelection . each ( ( d ) => { if ( d . taskType === selectedType && d . parent && ! d . selected ) { selectionHandler . handleSelection ( d , getEvent ( ) . ctrlKey ) ; } } ) ; } else { selectionHandler . handleClearSelection ( ) ; } } ) ; options . subTasksCollapse . selection . on ( "click" , ( d ) => { if ( ! _ . flatten ( d . tasks . map ( task => task . children ) ) . length ) { return ; } ( d3 . event as MouseEvent ) . stopPropagation ( ) ; options . subTasksCollapse . callback ( d ) ; } ) ; options . allSubtasksCollapse . selection . on ( "click" , ( ) => { ( d3 . event as MouseEvent ) . stopPropagation ( ) ; options . allSubtasksCollapse . callback ( ) ; } ) ; clearCatcher . on ( "click" , ( ) => { selectionHandler . handleClearSelection ( ) ; } ) ; } public renderSelection ( hasSelection ) { const { taskSelection , interactivityService , } = this . options ; const hasHighlights = interactivityService . hasSelection ( ) ; taskSelection . style ( "opacity" , ( dataPoint ) => { return getFillOpacity ( dataPoint . selected , dataPoint . highlight , ! dataPoint . highlight && hasSelection , ! dataPoint . selected && hasHighlights ) ; } ) ; } }