aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Charles Nicholson <nicholsonc@google.com>2016-11-15 11:17:43 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-11-15 11:25:49 -0800
commitaaa1f1a35ad2d584100d5524a547d8f92be755c4 (patch)
tree6552ed093951428fb1755956e18a1a972a021910
parentff01301128a23bbe1c03d9f8c677f5f076989016 (diff)
RGB Uint8 arrays for canvas label fill and stroke styles. Allows us to change
the label coloring for selected / hover / neighbor points, coming soon. Change: 139223883
-rw-r--r--tensorflow/tensorboard/components/vz_projector/projectorScatterPlotAdapter.ts36
-rw-r--r--tensorflow/tensorboard/components/vz_projector/renderContext.ts68
-rw-r--r--tensorflow/tensorboard/components/vz_projector/scatterPlotVisualizerCanvasLabels.ts40
3 files changed, 64 insertions, 80 deletions
diff --git a/tensorflow/tensorboard/components/vz_projector/projectorScatterPlotAdapter.ts b/tensorflow/tensorboard/components/vz_projector/projectorScatterPlotAdapter.ts
index 881be3989a..2d8c790747 100644
--- a/tensorflow/tensorboard/components/vz_projector/projectorScatterPlotAdapter.ts
+++ b/tensorflow/tensorboard/components/vz_projector/projectorScatterPlotAdapter.ts
@@ -20,8 +20,8 @@ import {LabelRenderParams} from './renderContext';
const LABEL_FONT_SIZE = 10;
const LABEL_SCALE_DEFAULT = 1.0;
const LABEL_SCALE_LARGE = 2;
-const LABEL_FILL_COLOR = 0x000000;
-const LABEL_STROKE_COLOR = 0xFFFFFF;
+const LABEL_FILL_COLOR = '#000000';
+const LABEL_STROKE_COLOR = '#FFFFFF';
const POINT_COLOR_UNSELECTED = 0xE3E3E3;
const POINT_COLOR_NO_SELECTION = 0x7575D9;
@@ -104,6 +104,14 @@ export class ProjectorScatterPlotAdapter {
return positions;
}
+ private packRgbIntoUint8Array(
+ rgbArray: Uint8Array, labelIndex: number, r: number, g: number,
+ b: number) {
+ rgbArray[labelIndex * 3] = r;
+ rgbArray[labelIndex * 3 + 1] = g;
+ rgbArray[labelIndex * 3 + 2] = b;
+ }
+
generateVisibleLabelRenderParams(
ds: DataSet, selectedPointIndices: number[],
neighborsOfFirstPoint: NearestEntry[],
@@ -118,6 +126,11 @@ export class ProjectorScatterPlotAdapter {
const visibleLabels = new Uint32Array(n);
const scale = new Float32Array(n);
const opacityFlags = new Int8Array(n);
+ const fillColors = new Uint8Array(n * 3);
+ const strokeColors = new Uint8Array(n * 3);
+
+ const fillRgb = d3.rgb(LABEL_FILL_COLOR);
+ const strokeRgb = d3.rgb(LABEL_STROKE_COLOR);
scale.fill(LABEL_SCALE_DEFAULT);
opacityFlags.fill(1);
@@ -128,6 +141,10 @@ export class ProjectorScatterPlotAdapter {
visibleLabels[dst] = hoverPointIndex;
scale[dst] = LABEL_SCALE_LARGE;
opacityFlags[dst] = 0;
+ this.packRgbIntoUint8Array(
+ fillColors, dst, fillRgb.r, fillRgb.g, fillRgb.b);
+ this.packRgbIntoUint8Array(
+ strokeColors, dst, strokeRgb.r, strokeRgb.g, strokeRgb.b);
++dst;
}
@@ -138,6 +155,10 @@ export class ProjectorScatterPlotAdapter {
visibleLabels[dst] = selectedPointIndices[i];
scale[dst] = LABEL_SCALE_LARGE;
opacityFlags[dst] = (n === 1) ? 0 : 1;
+ this.packRgbIntoUint8Array(
+ fillColors, dst, fillRgb.r, fillRgb.g, fillRgb.b);
+ this.packRgbIntoUint8Array(
+ strokeColors, dst, strokeRgb.r, strokeRgb.g, strokeRgb.b);
++dst;
}
}
@@ -146,13 +167,18 @@ export class ProjectorScatterPlotAdapter {
{
const n = neighborsOfFirstPoint.length;
for (let i = 0; i < n; ++i) {
- visibleLabels[dst++] = neighborsOfFirstPoint[i].index;
+ visibleLabels[dst] = neighborsOfFirstPoint[i].index;
+ this.packRgbIntoUint8Array(
+ fillColors, dst, fillRgb.r, fillRgb.g, fillRgb.b);
+ this.packRgbIntoUint8Array(
+ strokeColors, dst, strokeRgb.r, strokeRgb.g, strokeRgb.b);
+ ++dst;
}
}
return new LabelRenderParams(
- visibleLabels, scale, opacityFlags, LABEL_FONT_SIZE, LABEL_FILL_COLOR,
- LABEL_STROKE_COLOR);
+ visibleLabels, scale, opacityFlags, LABEL_FONT_SIZE, fillColors,
+ strokeColors);
}
generatePointScaleFactorArray(
diff --git a/tensorflow/tensorboard/components/vz_projector/renderContext.ts b/tensorflow/tensorboard/components/vz_projector/renderContext.ts
index 115965a6ed..544f23538c 100644
--- a/tensorflow/tensorboard/components/vz_projector/renderContext.ts
+++ b/tensorflow/tensorboard/components/vz_projector/renderContext.ts
@@ -18,24 +18,10 @@ limitations under the License.
* rendered next to them.
*/
export class LabelRenderParams {
- pointIndices: Float32Array;
- scaleFactors: Float32Array;
- useSceneOpacityFlags: Int8Array; // booleans
- defaultFontSize: number;
- fillColor: number;
- strokeColor: number;
-
constructor(
- pointIndices: Float32Array, scaleFactors: Float32Array,
- useSceneOpacityFlags: Int8Array, defaultFontSize: number,
- fillColor: number, strokeColor: number) {
- this.pointIndices = pointIndices;
- this.scaleFactors = scaleFactors;
- this.useSceneOpacityFlags = useSceneOpacityFlags;
- this.defaultFontSize = defaultFontSize;
- this.fillColor = fillColor;
- this.strokeColor = strokeColor;
- }
+ public pointIndices: Float32Array, public scaleFactors: Float32Array,
+ public useSceneOpacityFlags: Int8Array, public defaultFontSize: number,
+ public fillColors: Uint8Array, public strokeColors: Uint8Array) {}
}
/** Details about the camera projection being used to render the scene. */
@@ -53,44 +39,14 @@ export enum CameraType {
* only when they change.
*/
export class RenderContext {
- camera: THREE.Camera;
- cameraType: CameraType;
- cameraTarget: THREE.Vector3;
- screenWidth: number;
- screenHeight: number;
- nearestCameraSpacePointZ: number;
- farthestCameraSpacePointZ: number;
- backgroundColor: number;
- pointColors: Float32Array;
- pointScaleFactors: Float32Array;
- labelAccessor: (index: number) => string;
- labels: LabelRenderParams;
- traceColors: {[trace: number]: Float32Array};
- traceOpacities: Float32Array;
- traceWidths: Float32Array;
-
constructor(
- camera: THREE.Camera, cameraType: CameraType, cameraTarget: THREE.Vector3,
- screenWidth: number, screenHeight: number,
- nearestCameraSpacePointZ: number, farthestCameraSpacePointZ: number,
- backgroundColor: number, pointColors: Float32Array,
- pointScaleFactors: Float32Array, labelAccessor: (index: number) => string,
- labels: LabelRenderParams, traceColors: {[trace: number]: Float32Array},
- traceOpacities: Float32Array, traceWidths: Float32Array) {
- this.camera = camera;
- this.cameraType = cameraType;
- this.cameraTarget = cameraTarget;
- this.screenWidth = screenWidth;
- this.screenHeight = screenHeight;
- this.nearestCameraSpacePointZ = nearestCameraSpacePointZ;
- this.farthestCameraSpacePointZ = farthestCameraSpacePointZ;
- this.backgroundColor = backgroundColor;
- this.pointColors = pointColors;
- this.pointScaleFactors = pointScaleFactors;
- this.labelAccessor = labelAccessor;
- this.labels = labels;
- this.traceColors = traceColors;
- this.traceOpacities = traceOpacities;
- this.traceWidths = traceWidths;
- }
+ public camera: THREE.Camera, public cameraType: CameraType,
+ public cameraTarget: THREE.Vector3, public screenWidth: number,
+ public screenHeight: number, public nearestCameraSpacePointZ: number,
+ public farthestCameraSpacePointZ: number, public backgroundColor: number,
+ public pointColors: Float32Array, public pointScaleFactors: Float32Array,
+ public labelAccessor: (index: number) => string,
+ public labels: LabelRenderParams,
+ public traceColors: {[trace: number]: Float32Array},
+ public traceOpacities: Float32Array, public traceWidths: Float32Array) {}
}
diff --git a/tensorflow/tensorboard/components/vz_projector/scatterPlotVisualizerCanvasLabels.ts b/tensorflow/tensorboard/components/vz_projector/scatterPlotVisualizerCanvasLabels.ts
index 58d52f39e6..e6439d6849 100644
--- a/tensorflow/tensorboard/components/vz_projector/scatterPlotVisualizerCanvasLabels.ts
+++ b/tensorflow/tensorboard/components/vz_projector/scatterPlotVisualizerCanvasLabels.ts
@@ -53,17 +53,9 @@ export class ScatterPlotVisualizerCanvasLabels implements
return;
}
+ const lrc = rc.labels;
const sceneIs3D: boolean = (rc.cameraType === CameraType.Perspective);
- let strokeStylePrefix: string;
- let fillStylePrefix: string;
- {
- const ls = new THREE.Color(rc.labels.strokeColor).multiplyScalar(255);
- const lc = new THREE.Color(rc.labels.fillColor).multiplyScalar(255);
- strokeStylePrefix = 'rgba(' + ls.r + ',' + ls.g + ',' + ls.b + ',';
- fillStylePrefix = 'rgba(' + lc.r + ',' + lc.g + ',' + lc.b + ',';
- }
-
const labelHeight = parseInt(this.gc.font, 10);
const dpr = window.devicePixelRatio;
@@ -75,9 +67,11 @@ export class ScatterPlotVisualizerCanvasLabels implements
grid = new CollisionGrid(bb, pixw / 25, pixh / 50);
}
- let opacityMap = d3.scale.pow().exponent(Math.E)
- .domain([rc.farthestCameraSpacePointZ, rc.nearestCameraSpacePointZ])
- .range([0.1, 1]);
+ let opacityMap =
+ d3.scale.pow()
+ .exponent(Math.E)
+ .domain([rc.farthestCameraSpacePointZ, rc.nearestCameraSpacePointZ])
+ .range([0.1, 1]);
const camPos = rc.camera.position;
const camToTarget = camPos.clone().sub(rc.cameraTarget);
@@ -91,9 +85,9 @@ export class ScatterPlotVisualizerCanvasLabels implements
// Shift the label to the right of the point circle.
const xShift = 4;
- const n = Math.min(MAX_LABELS_ON_SCREEN, rc.labels.pointIndices.length);
+ const n = Math.min(MAX_LABELS_ON_SCREEN, lrc.pointIndices.length);
for (let i = 0; i < n; ++i) {
- const index = rc.labels.pointIndices[i];
+ const index = lrc.pointIndices[i];
const point =
util.vector3FromPackedArray(this.worldSpacePointPositions, index);
@@ -119,19 +113,22 @@ export class ScatterPlotVisualizerCanvasLabels implements
if (grid.insert(textBoundingBox, true)) {
const text = rc.labelAccessor(index);
- const fontSize =
- rc.labels.defaultFontSize * rc.labels.scaleFactors[i] * dpr;
+ const fontSize = lrc.defaultFontSize * lrc.scaleFactors[i] * dpr;
this.gc.font = fontSize + 'px roboto';
// Now, check with properly computed width.
textBoundingBox.hiX += this.gc.measureText(text).width - 1;
if (grid.insert(textBoundingBox)) {
let opacity = 1;
- if (sceneIs3D && (rc.labels.useSceneOpacityFlags[i] === 1)) {
+ if (sceneIs3D && (lrc.useSceneOpacityFlags[i] === 1)) {
opacity = opacityMap(camToPoint.length());
}
- this.gc.fillStyle = fillStylePrefix + opacity + ')';
- this.gc.strokeStyle = strokeStylePrefix + opacity + ')';
+ this.gc.fillStyle = this.styleStringFromRGBA(
+ lrc.fillColors[i * 3], lrc.fillColors[i * 3 + 1],
+ lrc.fillColors[i * 3 + 2], opacity);
+ this.gc.strokeStyle = this.styleStringFromRGBA(
+ lrc.strokeColors[i * 3], lrc.strokeColors[i * 3 + 1],
+ lrc.strokeColors[i * 3 + 2], opacity);
this.gc.lineWidth = LABEL_STROKE_WIDTH;
this.gc.strokeText(text, x, y);
this.gc.lineWidth = LABEL_FILL_WIDTH;
@@ -141,6 +138,11 @@ export class ScatterPlotVisualizerCanvasLabels implements
}
}
+ private styleStringFromRGBA(r: number, g: number, b: number, a: number):
+ string {
+ return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
+ }
+
onResize(newWidth: number, newHeight: number) {
let dpr = window.devicePixelRatio;
d3.select(this.canvas)