public update()

in packages/attribute-slicer-powerbi/src/AttributeSlicerVisual.ts [162:232]


	public update(options: VisualUpdateOptions): void {
		this.events.renderingStarted(options);

		this.isHandlingUpdate = true;

		const isAllUpdate = options.type === VisualUpdateType.All;
		const isResizeUpdate =
			!this.dims ||
			this.dims.height !== options.viewport.height ||
			this.dims.width !== options.viewport.width;
		const isDataUpdate = options.type === VisualUpdateType.Data || isAllUpdate;
		try {
			if (isResizeUpdate) {
				this.dims = options.viewport;
				this.mySlicer.dimensions = options.viewport;
			}

			// We should ALWAYS have a dataView, if we do not, PBI has not loaded yet
			const dv: DataView | undefined = (this.dataView =
				options.dataViews && options.dataViews[0]);

			// For some reason, there are situations in where you have a dataView, but it is missing data!
			if (dv && dv.categorical) {
				const newState: AttributeSlicerVisualState = AttributeSlicerVisualState.CREATE_FROM_POWERBI(
					dv,
					() => this.host.createSelectionIdBuilder(),
				);
				this.loadDataFromVisualUpdate(isDataUpdate, dv, newState);

				// The old state passed in the params, is the old *cached* version,
				// so if we change the state ourselves, then oldState will not actually
				// reflect the correct old state. Since the other one is cached.
				if (!isStateEqual(newState, this.state)) {
					const oldState: AttributeSlicerVisualState = this.state;
					this.state = newState;
					this.mySlicer.state = newState;

					const { labelPrecision, labelDisplayUnits } = this.state;
					if ((labelPrecision || labelDisplayUnits) && this.mySlicer.data) {
						const formatter: IValueFormatter = createValueFormatter(
							labelDisplayUnits,
							labelPrecision,
						);

						// Update the display values in the datas
						this.mySlicer.data.forEach((n: ISlicerItem) => {
							(n.valueSegments || []).forEach((segment: IValueSegment) => {
								segment.displayValue = formatter.format(segment.value);
							});
						});

						// Tell the slicer to repaint
						this.mySlicer.refresh();
					}

					// The colors have changed, so we need to reload data
					if (!oldState.colors.equals(newState.colors)) {
						this.data = this.convertData(dv, this.state);
						this.mySlicer.data = this.data.items;
						this.mySlicer.selectedItems = (
							this.state.selectedItems || []
						).slice(0); // make a copy
					}
					this.mySlicer.scrollPosition = newState.scrollPosition;
				}
			}
		} finally {
			this.isHandlingUpdate = false;
			this.events.renderingFinished(options);
		}
	}