in tensorboard/components/tensor_widget/tensor-widget-impl.ts [395:528]
private async renderValues() {
if (this.rank > 2 && this.slicingSpecRoot === null) {
this.slicingSpecRoot = document.createElement('div');
this.slicingSpecRoot.classList.add('tensor-widget-slicing-group');
this.rootElement.appendChild(this.slicingSpecRoot);
}
if (this.valueSection == null) {
this.valueSection = document.createElement('div');
this.valueSection.classList.add('tensor-widget-value-section');
this.rootElement.appendChild(this.valueSection);
this.valueSection.addEventListener('wheel', async (event) => {
let zoomKeyPressed = false;
if (
this.options.wheelZoomKey == null ||
this.options.wheelZoomKey === 'ctrl'
) {
zoomKeyPressed = event.ctrlKey;
} else if (this.options.wheelZoomKey === 'alt') {
zoomKeyPressed = event.altKey;
} else if (this.options.wheelZoomKey === 'shift') {
zoomKeyPressed = event.shiftKey;
}
if (zoomKeyPressed && this.valueRenderMode === ValueRenderMode.IMAGE) {
event.stopPropagation();
event.preventDefault();
if (event.deltaY > 0) {
this.zoomOutOneStepAndRenderValues();
} else {
this.zoomInOneStepAndRenderValues();
}
return;
}
if (this.selection == null) {
return;
}
event.stopPropagation();
event.preventDefault();
this.hideValueTooltip();
await this.scrollUpOrDown(
event.deltaY > 0 ? MoveDirection.DOWN : MoveDirection.UP
);
});
// Add event listener for the value section.
this.valueSection.tabIndex = 1024;
this.valueSection.addEventListener('keydown', (event) => {
const UP_KEYCODE = 38;
const DOWN_KEYCODE = 40;
const LEFT_KEYCODE = 37;
const RIGHT_KEYCODE = 39;
const VALID_KEYCODES = [
UP_KEYCODE,
DOWN_KEYCODE,
LEFT_KEYCODE,
RIGHT_KEYCODE,
];
if (
this.selection != null &&
VALID_KEYCODES.indexOf(event.keyCode) !== -1
) {
event.stopPropagation();
event.preventDefault();
this.hideValueTooltip();
let slicingMoveDirection: MoveDirection | null = null;
let moveDirection: MoveDirection | null = null;
if (event.keyCode === UP_KEYCODE) {
moveDirection = MoveDirection.UP;
} else if (event.keyCode === DOWN_KEYCODE) {
moveDirection = MoveDirection.DOWN;
} else if (event.keyCode === LEFT_KEYCODE) {
moveDirection = MoveDirection.LEFT;
} else if (event.keyCode === RIGHT_KEYCODE) {
moveDirection = MoveDirection.RIGHT;
}
if (moveDirection !== null) {
slicingMoveDirection = this.selection.move(
moveDirection,
this.slicingSpec
);
}
// The selection movement may necessitate a change in the vertical or
// horizontal view.
if (slicingMoveDirection === null) {
this.renderSelection();
} else if (
slicingMoveDirection === MoveDirection.UP ||
slicingMoveDirection === MoveDirection.DOWN
) {
this.scrollUpOrDown(slicingMoveDirection);
} else if (
slicingMoveDirection === MoveDirection.LEFT ||
slicingMoveDirection === MoveDirection.RIGHT
) {
this.scrollLeftOrRight(slicingMoveDirection);
}
}
});
}
this.clearValueSection();
this.createTopRuler();
this.createLeftRuler();
this.createValueDivs();
await this.renderRulersAndValueDivs();
if (this.rank > 2) {
this.slicingControl = new SlicingControl(
this.slicingSpecRoot as HTMLDivElement,
this.tensorView.spec.shape,
async (slicingSpec: TensorViewSlicingSpec) => {
if (!areSlicingSpecsCompatible(this.slicingSpec, slicingSpec)) {
this.slicingSpec = JSON.parse(
JSON.stringify(slicingSpec)
) as TensorViewSlicingSpec;
// The dimension arrangement has changed in the slicing spec.
// The rulers and value divs must be re-created. This is why
// `render()` is called instead of `renderRulersAndValueDivs()`.
await this.render();
} else {
this.slicingSpec = JSON.parse(
JSON.stringify(slicingSpec)
) as TensorViewSlicingSpec;
await this.renderRulersAndValueDivs();
}
}
);
this.slicingControl.render(this.slicingSpec);
}
}