aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-04-24 23:00:26 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-04-24 23:00:26 -0400
commit896c0fef965458bd23ff098c7c95b09799528033 (patch)
tree4be10fdcd7bd766b0cb85718540c248bb2596e37
parentf5b6837dba732780930594e76a3676a4264639d7 (diff)
changed pivot view to support lists of values for keys (docs can appear mulltiple times as replicas)
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx122
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx47
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx5
3 files changed, 100 insertions, 74 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 9f7919ada..d8bd18ec7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -9,6 +9,7 @@ import React = require("react");
import { Id, ToString } from "../../../../new_fields/FieldSymbols";
import { ObjectField } from "../../../../new_fields/ObjectField";
import { RefField } from "../../../../new_fields/RefField";
+import { listSpec } from "../../../../new_fields/Schema";
export interface ViewDefBounds {
type: string;
@@ -24,6 +25,8 @@ export interface ViewDefBounds {
highlight?: boolean;
color?: string;
payload: any;
+ replica?: string;
+ pair?: { layout: Doc, data?: Doc };
}
export interface PoolData {
@@ -36,6 +39,8 @@ export interface PoolData {
color?: string;
transition?: string;
highlight?: boolean;
+ replica?: string;
+ pair: { layout: Doc, data?: Doc }
}
export interface ViewDefResult {
@@ -72,100 +77,111 @@ function getTextWidth(text: string, font: string): number {
interface PivotColumn {
docs: Doc[];
+ replicas: string[];
filters: string[];
}
export function computerPassLayout(
poolData: Map<string, PoolData>,
pivotDoc: Doc,
- childDocs: Doc[],
filterDocs: Doc[],
childPairs: { layout: Doc, data?: Doc }[],
panelDim: number[],
viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[]
) {
- const docMap = new Map<Doc, ViewDefBounds>();
- childDocs.forEach((doc, i) => {
- docMap.set(doc, {
+ const docMap = new Map<string, ViewDefBounds>();
+ childPairs.forEach(({ layout, data }, i) => {
+ docMap.set(layout[Id], {
type: "doc",
- x: NumCast(doc.x),
- y: NumCast(doc.y),
- width: doc[WidthSym](),
- height: doc[HeightSym](),
- payload: undefined
+ x: NumCast(layout.x),
+ y: NumCast(layout.y),
+ width: layout[WidthSym](),
+ height: layout[HeightSym](),
+ payload: undefined,
+ pair: { layout, data },
+ replica: ""
});
});
- return normalizeResults(panelDim, 12, childPairs, docMap, poolData, viewDefsToJSX, [], 0, [], childDocs.filter(c => !filterDocs.includes(c)));
+ return normalizeResults(panelDim, 12, childPairs, docMap, poolData, viewDefsToJSX, [], 0, [], childPairs.filter(c => !filterDocs.includes(c.layout)));
}
export function computerStarburstLayout(
poolData: Map<string, PoolData>,
pivotDoc: Doc,
- childDocs: Doc[],
filterDocs: Doc[],
childPairs: { layout: Doc, data?: Doc }[],
panelDim: number[],
viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[]
) {
- const docMap = new Map<Doc, ViewDefBounds>();
+ const docMap = new Map<string, ViewDefBounds>();
const burstRadius = [NumCast(pivotDoc._starburstRadius, panelDim[0]), NumCast(pivotDoc._starburstRadius, panelDim[1])];
const docScale = NumCast(pivotDoc._starburstDocScale);
const docSize = docScale * 100; // assume a icon sized at 100
const scaleDim = [burstRadius[0] + docSize, burstRadius[1] + docSize];
- childDocs.forEach((doc, i) => {
- const deg = i / childDocs.length * Math.PI * 2;
- docMap.set(doc, {
+ childPairs.forEach((pair, i) => {
+ const deg = i / childPairs.length * Math.PI * 2;
+ docMap.set(pair.layout[Id], {
type: "doc",
- x: Math.cos(deg) * (burstRadius[0] / 3) - docScale * doc[WidthSym]() / 2,
- y: Math.sin(deg) * (burstRadius[1] / 3) - docScale * doc[HeightSym]() / 2,
- width: docScale * doc[WidthSym](),
- height: docScale * doc[HeightSym](),
- payload: undefined
+ x: Math.cos(deg) * (burstRadius[0] / 3) - docScale * pair.layout[WidthSym]() / 2,
+ y: Math.sin(deg) * (burstRadius[1] / 3) - docScale * pair.layout[HeightSym]() / 2,
+ width: docScale * pair.layout[WidthSym](),
+ height: docScale * pair.layout[HeightSym](),
+ payload: undefined,
+ replica: ""
});
});
- return normalizeResults(scaleDim, 12, childPairs, docMap, poolData, viewDefsToJSX, [], 0, [], childDocs.filter(c => !filterDocs.includes(c)));
+ return normalizeResults(scaleDim, 12, childPairs, docMap, poolData, viewDefsToJSX, [], 0, [], childPairs.filter(c => !filterDocs.includes(c.layout)));
}
export function computePivotLayout(
poolData: Map<string, PoolData>,
pivotDoc: Doc,
- childDocs: Doc[],
filterDocs: Doc[],
childPairs: { layout: Doc, data?: Doc }[],
panelDim: number[],
viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[]
) {
- const docMap = new Map<Doc, ViewDefBounds>();
+ const docMap = new Map<string, ViewDefBounds>();
const fieldKey = "data";
const pivotColumnGroups = new Map<FieldResult<Field>, PivotColumn>();
const pivotFieldKey = toLabel(pivotDoc._pivotField);
for (const doc of filterDocs) {
+ const lval = Cast(doc[pivotFieldKey], listSpec("string"), null);
const val = Field.toString(doc[pivotFieldKey] as Field);
- if (val) {
- !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val] });
+ if (lval) {
+ lval.forEach((val, i) => {
+ !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] });
+ pivotColumnGroups.get(val)!.docs.push(doc);
+ pivotColumnGroups.get(val)!.replicas.push(i.toString());
+ });
+ } else if (val) {
+ !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] });
pivotColumnGroups.get(val)!.docs.push(doc);
+ pivotColumnGroups.get(val)!.replicas.push("");
} else {
- docMap.set(doc, {
+ docMap.set(doc[Id], {
type: "doc",
x: 0,
y: 0,
zIndex: -99,
width: 0,
height: 0,
- payload: undefined
+ payload: undefined,
+ pair: { layout: doc },
+ replica: ""
})
}
}
let nonNumbers = 0;
- childDocs.map(doc => {
- const num = toNumber(doc[pivotFieldKey]);
+ childPairs.map(pair => {
+ const num = toNumber(pair.layout[pivotFieldKey]);
if (num === undefined || Number.isNaN(num)) {
nonNumbers++;
}
});
- const pivotNumbers = nonNumbers / childDocs.length < .1;
+ const pivotNumbers = nonNumbers / childPairs.length < .1;
if (pivotColumnGroups.size > 10) {
const arrayofKeys = Array.from(pivotColumnGroups.keys());
const sortedKeys = pivotNumbers ? arrayofKeys.sort((n1: FieldResult, n2: FieldResult) => toNumber(n1)! - toNumber(n2)!) : arrayofKeys.sort();
@@ -177,6 +193,7 @@ export function computePivotLayout(
const newgrp = pivotColumnGroups.get(sortedKeys[j])!;
curgrp.docs.push(...newgrp.docs);
curgrp.filters.push(...newgrp.filters);
+ curgrp.replicas.push(...newgrp.replicas);
pivotColumnGroups.delete(sortedKeys[j]);
}
}
@@ -226,7 +243,7 @@ export function computePivotLayout(
fontSize,
payload: val
});
- for (const doc of val.docs) {
+ val.docs.forEach((doc, i) => {
const layoutDoc = Doc.Layout(doc);
let wid = pivotAxisWidth;
let hgt = layoutDoc._nativeWidth ? (NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth)) * pivotAxisWidth : pivotAxisWidth;
@@ -234,27 +251,29 @@ export function computePivotLayout(
hgt = pivotAxisWidth;
wid = layoutDoc._nativeHeight ? (NumCast(layoutDoc._nativeWidth) / NumCast(layoutDoc._nativeHeight)) * pivotAxisWidth : pivotAxisWidth;
}
- docMap.set(doc, {
+ docMap.set(doc[Id] + (val.replicas || ""), {
type: "doc",
x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2 + (val.docs.length < numCols ? (numCols - val.docs.length) * pivotAxisWidth / 2 : 0),
y: -y + (pivotAxisWidth - hgt) / 2,
width: wid,
height: hgt,
- payload: undefined
+ payload: undefined,
+ pair: { layout: doc },
+ replica: val.replicas[i]
});
xCount++;
if (xCount >= numCols) {
xCount = 0;
y += pivotAxisWidth * expander;
}
- }
+ });
x += pivotAxisWidth * (numCols * expander + gap);
});
const dividers = sortedPivotKeys.map((key, i) =>
({ type: "div", color: "lightGray", x: i * pivotAxisWidth * (numCols * expander + gap) - pivotAxisWidth * (expander - 1) / 2, y: -maxColHeight + pivotAxisWidth, width: pivotAxisWidth * numCols * expander, height: maxColHeight, payload: pivotColumnGroups.get(key)!.filters }));
groupNames.push(...dividers);
- return normalizeResults(panelDim, max_text, childPairs, docMap, poolData, viewDefsToJSX, groupNames, 0, [], childDocs.filter(c => !filterDocs.includes(c)));
+ return normalizeResults(panelDim, max_text, childPairs, docMap, poolData, viewDefsToJSX, groupNames, 0, [], childPairs.filter(c => !filterDocs.includes(c.layout)));
}
function toNumber(val: FieldResult<Field>) {
@@ -264,7 +283,6 @@ function toNumber(val: FieldResult<Field>) {
export function computeTimelineLayout(
poolData: Map<string, PoolData>,
pivotDoc: Doc,
- childDocs: Doc[],
filterDocs: Doc[],
childPairs: { layout: Doc, data?: Doc }[],
panelDim: number[],
@@ -272,7 +290,7 @@ export function computeTimelineLayout(
) {
const fieldKey = "data";
const pivotDateGroups = new Map<number, Doc[]>();
- const docMap = new Map<Doc, ViewDefBounds>();
+ const docMap = new Map<string, ViewDefBounds>();
const groupNames: ViewDefBounds[] = [];
const timelineFieldKey = Field.toString(pivotDoc._pivotField as Field);
const curTime = toNumber(pivotDoc[fieldKey + "-timelineCur"]);
@@ -351,7 +369,7 @@ export function computeTimelineLayout(
}
const divider = { type: "div", color: Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimGray" : "black", x: 0, y: 0, width: panelDim[0], height: -1, payload: undefined };
- return normalizeResults(panelDim, fontHeight, childPairs, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider], childDocs.filter(c => !filterDocs.includes(c)));
+ return normalizeResults(panelDim, fontHeight, childPairs, docMap, poolData, viewDefsToJSX, groupNames, (maxTime - minTime) * scaling, [divider], childPairs.filter(c => !filterDocs.includes(c.layout)));
function layoutDocsAtTime(keyDocs: Doc[], key: number) {
keyDocs.forEach(doc => {
@@ -363,43 +381,51 @@ export function computeTimelineLayout(
hgt = pivotAxisWidth;
wid = layoutDoc._nativeHeight ? (NumCast(layoutDoc._nativeWidth) / NumCast(layoutDoc._nativeHeight)) * pivotAxisWidth : pivotAxisWidth;
}
- docMap.set(doc, {
+ docMap.set(doc[Id], {
type: "doc",
x: x, y: -Math.sqrt(stack) * pivotAxisWidth / 2 - pivotAxisWidth + (pivotAxisWidth - hgt) / 2,
- zIndex: (curTime === key ? 1000 : zind++), highlight: curTime === key, width: wid / (Math.max(stack, 1)), height: hgt / (Math.max(stack, 1)), payload: undefined
+ zIndex: (curTime === key ? 1000 : zind++),
+ highlight: curTime === key,
+ width: wid / (Math.max(stack, 1)),
+ height: hgt / (Math.max(stack, 1)),
+ payload: undefined,
+ pair: { layout: doc },
+ replica: ""
});
stacking[stack] = x + pivotAxisWidth;
});
}
}
-function normalizeResults(panelDim: number[], fontHeight: number, childPairs: { data?: Doc, layout: Doc }[], docMap: Map<Doc, ViewDefBounds>,
+function normalizeResults(panelDim: number[], fontHeight: number, childPairs: { data?: Doc, layout: Doc }[], docMap: Map<string, ViewDefBounds>,
poolData: Map<string, PoolData>, viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], groupNames: ViewDefBounds[], minWidth: number, extras: ViewDefBounds[],
- extraDocs: Doc[]): ViewDefResult[] {
+ extraDocs: { data?: Doc, layout: Doc }[]): ViewDefResult[] {
const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height }) as ViewDefBounds);
- const docEles = childPairs.filter(d => docMap.get(d.layout)).map(pair => docMap.get(pair.layout) as ViewDefBounds);
+ const docEles = Array.from(docMap.entries()).map(ele => ele[1]);
const aggBounds = aggregateBounds(docEles.concat(grpEles).filter(e => e.zIndex !== -99), 0, 0);
aggBounds.r = Math.max(minWidth, aggBounds.r - aggBounds.x);
const wscale = panelDim[0] / (aggBounds.r - aggBounds.x);
let scale = wscale * (aggBounds.b - aggBounds.y) > panelDim[1] ? (panelDim[1]) / (aggBounds.b - aggBounds.y) : wscale;
if (Number.isNaN(scale)) scale = 1;
- childPairs.filter(d => docMap.get(d.layout)).map(pair => {
- const newPosRaw = docMap.get(pair.layout);
+ Array.from(docMap.entries()).filter(ele => ele[1].pair).map(ele => {
+ const newPosRaw = ele[1];
if (newPosRaw) {
const newPos = {
x: newPosRaw.x * scale,
y: newPosRaw.y * scale,
z: newPosRaw.z,
+ replica: newPosRaw.replica,
highlight: newPosRaw.highlight,
zIndex: newPosRaw.zIndex,
width: (newPosRaw.width || 0) * scale,
- height: newPosRaw.height! * scale
+ height: newPosRaw.height! * scale,
+ pair: ele[1].pair!
};
- poolData.set(pair.layout[Id], { transition: "transform 1s", ...newPos });
+ poolData.set(newPos.pair.layout[Id] + (newPos.replica || ""), { transition: "transform 1s", ...newPos });
}
});
- extraDocs.map(ed => poolData.set(ed[Id], { x: 0, y: 0, zIndex: -99 }));
+ extraDocs.map(ed => poolData.set(ed.layout[Id], { x: 0, y: 0, zIndex: -99, pair: ed }));
return viewDefsToJSX(extras.concat(groupNames).map(gname => ({
type: gname.type,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b3cf2b97a..5555d9e84 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -85,8 +85,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
private _clusterDistance: number = 75;
private _hitCluster = false;
private _layoutComputeReaction: IReactionDisposer | undefined;
- private _layoutPoolData = new ObservableMap<string, any>();
- private _cachedPool: Map<string, any> = new Map();
+ private _layoutPoolData = new ObservableMap<string, PoolData>();
+ private _cachedPool: Map<string, PoolData> = new Map();
@observable private _pullCoords: number[] = [0, 0];
@observable private _pullDirection: string = "";
@@ -728,7 +728,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
if (!this.isAnnotationOverlay && clamp) {
// this section wraps the pan position, horizontally and/or vertically whenever the content is panned out of the viewing bounds
const docs = this.childLayoutPairs.filter(pair => pair.layout instanceof Doc).map(pair => pair.layout);
- const measuredDocs = docs.filter(doc => doc && this.childDataProvider(doc)).map(doc => this.childDataProvider(doc));
+ const measuredDocs = docs.filter(doc => doc && this.childDataProvider(doc, "")).map(doc => this.childDataProvider(doc, ""));
if (measuredDocs.length) {
const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) => // computes range of content
({
@@ -899,16 +899,16 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
return this.props.addDocTab(doc, where);
});
- getCalculatedPositions(params: { doc: Doc, index: number, collection: Doc, docs: Doc[], state: any }): PoolData {
+ getCalculatedPositions(params: { pair: { layout: Doc, data?: Doc }, index: number, collection: Doc, docs: Doc[], state: any }): PoolData {
const result = this.Document.arrangeScript?.script.run(params, console.log);
if (result?.success) {
- return { ...result, transition: "transform 1s" };
+ return { ...result, pair: params.pair, transition: "transform 1s" };
}
- const layoutDoc = Doc.Layout(params.doc);
- const { x, y, z, color, zIndex } = params.doc;
+ const layoutDoc = Doc.Layout(params.pair.layout);
+ const { x, y, z, color, zIndex } = params.pair.layout;
return {
x: NumCast(x), y: NumCast(y), z: Cast(z, "number"), color: StrCast(color), zIndex: Cast(zIndex, "number"),
- width: Cast(layoutDoc._width, "number"), height: Cast(layoutDoc._height, "number")
+ width: Cast(layoutDoc._width, "number"), height: Cast(layoutDoc._height, "number"), pair: params.pair
};
}
@@ -946,20 +946,19 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
}
- childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc) {
- return this._layoutPoolData.get(doc[Id]);
+ childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc, replica: Opt<string>) {
+ return this._layoutPoolData.get(doc[Id] + (replica || ""));
}.bind(this));
doEngineLayout(poolData: Map<string, PoolData>,
engine: (
poolData: Map<string, PoolData>,
pivotDoc: Doc,
- childDocs: Doc[],
filterDocs: Doc[],
childPairs: { layout: Doc, data?: Doc }[],
panelDim: number[],
viewDefsToJSX: ((views: ViewDefBounds[]) => ViewDefResult[])) => ViewDefResult[]) {
- return engine(poolData, this.props.Document, this.childDocs, this.childDocs,
+ return engine(poolData, this.props.Document, this.childDocs,
this.childLayoutPairs, [this.props.PanelWidth(), this.props.PanelHeight()], this.viewDefsToJSX);
}
@@ -970,14 +969,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => {
- const pos = this.getCalculatedPositions({ doc: pair.layout, index: i, collection: this.Document, docs: layoutDocs, state });
+ const pos = this.getCalculatedPositions({ pair, index: i, collection: this.Document, docs: layoutDocs, state });
poolData.set(pair.layout[Id], pos);
});
return elements;
}
@computed get doInternalLayoutComputation() {
- const newPool = new Map<string, any>();
+ const newPool = new Map<string, PoolData>();
const engine = StrCast(this.layoutDoc._layoutEngine) || this.props.layoutEngine?.();
switch (engine) {
case "pass": return { newPool, computedElementData: this.doEngineLayout(newPool, computerPassLayout) };
@@ -992,22 +991,22 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
get doLayoutComputation() {
const { newPool, computedElementData } = this.doInternalLayoutComputation;
runInAction(() =>
- Array.from(newPool.keys()).map(key => {
- const lastPos = this._cachedPool.get(key); // last computed pos
- const newPos = newPool.get(key);
+ Array.from(newPool.entries()).map(entry => {
+ const lastPos = this._cachedPool.get(entry[0]); // last computed pos
+ const newPos = entry[1];
if (!lastPos || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.zIndex !== lastPos.zIndex || newPos.width !== lastPos.width || newPos.height !== lastPos.height) {
- this._layoutPoolData.set(key, newPos);
+ this._layoutPoolData.set(entry[0], newPos);
}
}));
this._cachedPool.clear();
- Array.from(newPool.keys()).forEach(k => this._cachedPool.set(k, newPool.get(k)));
+ Array.from(newPool.entries()).forEach(k => this._cachedPool.set(k[0], k[1]));
const elements: ViewDefResult[] = computedElementData.slice();
- const engine = this.props.layoutEngine?.() || this.props.Document._layoutEngine;
- this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).forEach(pair =>
+ Array.from(newPool.entries()).filter(entry => this.isCurrent(entry[1].pair.layout)).forEach(entry =>
elements.push({
ele: <CollectionFreeFormDocumentView
- key={pair.layout[Id]}
- {...this.getChildDocumentViewProps(pair.layout, pair.data)}
+ key={entry[1].pair.layout[Id] + (entry[1].replica || "")}
+ {...this.getChildDocumentViewProps(entry[1].pair.layout, entry[1].pair.data)}
+ replica={entry[1].replica}
dataProvider={this.childDataProvider}
LayoutDoc={this.childLayoutDocFunc}
pointerEvents={this.props.viewDefDivClick ? false : undefined}
@@ -1015,7 +1014,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
fitToBox={this.props.fitToBox || BoolCast(this.props.freezeChildDimensions)}
FreezeDimensions={BoolCast(this.props.freezeChildDimensions)}
/>,
- bounds: this.childDataProvider(pair.layout)
+ bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica)
}));
return elements;
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 4b282b0c9..baeac311e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -12,7 +12,7 @@ import { TraceMobx } from "../../../new_fields/util";
import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
- dataProvider?: (doc: Doc) => { x: number, y: number, zIndex?: number, highlight?: boolean, width: number, height: number, z: number, transition?: string } | undefined;
+ dataProvider?: (doc: Doc, replica?: string) => { x: number, y: number, zIndex?: number, highlight?: boolean, width: number, height: number, z: number, transition?: string, replica: string } | undefined;
x?: number;
y?: number;
z?: number;
@@ -23,6 +23,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
jitterRotation: number;
transition?: string;
fitToBox?: boolean;
+ replica?: string;
}
@observer
@@ -46,7 +47,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
return (hgt === undefined && this.nativeWidth && this.nativeHeight) ? this.width * this.nativeHeight / this.nativeWidth : hgt;
}
@computed get freezeDimensions() { return this.props.FreezeDimensions; }
- @computed get dataProvider() { return this.props.dataProvider && this.props.dataProvider(this.props.Document) ? this.props.dataProvider(this.props.Document) : undefined; }
+ @computed get dataProvider() { return this.props.dataProvider?.(this.props.Document, this.props.replica); }
@computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth, this.props.NativeWidth() || (this.freezeDimensions ? this.layoutDoc[WidthSym]() : 0)); }
@computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight, this.props.NativeHeight() || (this.freezeDimensions ? this.layoutDoc[HeightSym]() : 0)); }