mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-03 17:38:11 +08:00
TS Revert (1) (#2402)
* revert all commits to before Typescript migration * update compat workflow to match latest deps (#2335) * update compat workflow to match latest deps * attempt to debug * attempt to debug * remove debugging code * typo * update deps to match desktop (#2340) * fix: don't run lint with `--fix` on push tests (#2273) * fix: don't run lint with `--fix` on push tests * npx Co-authored-by: maniarathi <mani.arathi@gmail.com> Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com> * rename X_approx_distribution to X_approximate_distribution (#2337) * Correctly handle non-finite numbers in heuristic determination of X distribution (#2342) * handle non-finites explicitly * improve and test edge case handling for distribution estimation * revert debugging changes * code readability * clean up type inferencing (#2332) * unit tests for 64 bit conversion * clean up type handling * type inference tests * more type inference fixes * use schema to determine user intent for data typing * stop using deprecated API * fbs type encoding test * add missing test * add more tests * correctly infer X type for CXG adaptor * lint * fix typo * ts migration * cleanup from PR review * lint * PR review changes * remove unused packages from client (#2359) * remove unused packages from client * add missing peer dep * fix: disable FE auth testing on compatibility tests (#2377) * update: release process (#2277) Co-authored-by: maniarathi <mani.arathi@gmail.com> * fix: remove spaces in param setup (#2380) * delete deploy workflow (#2396) * undo reformatting which now does not pass lint * fix snapshots which changed due to npm dep changes * add missing quoting to snapshot * another snapshot typo fix * TS Revert (2) - replay PR #2347 and #2354 (#2403) * replay edits from PR 2347 * TS Revert (3) - replay edits in PR #2327 (#2404) * replay edits in PR 2327 * TS Revert (4) - replay PR #2355 (#2405) * replay edits in PR 2355 * add additional babel config * reformat with new prettier config Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com> Co-authored-by: maniarathi <mani.arathi@gmail.com> Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com>
This commit is contained in:
co-authored by
maniarathi
Madison Dunitz
Severiano Badajoz
parent
295590a7c6
commit
eaae6df5e3
+1
-2
@@ -1,7 +1,6 @@
|
||||
import { glPointFlags, glPointSize } from "../../util/glHelpers";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export default function drawPointsRegl(regl: any) {
|
||||
export default function drawPointsRegl(regl) {
|
||||
return regl({
|
||||
vert: `
|
||||
precision mediump float;
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
flagSelected,
|
||||
flagHighlight,
|
||||
} from "../../util/glHelpers";
|
||||
import { Dataframe } from "../../util/dataframe";
|
||||
|
||||
/*
|
||||
Simple 2D transforms control all point painting. There are three:
|
||||
@@ -35,8 +34,7 @@ Simple 2D transforms control all point painting. There are three:
|
||||
* camera - apply a 2D camera transformation (pan, zoom)
|
||||
* projection - apply any transformation required for screen size and layout
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
function createProjectionTF(viewportWidth: any, viewportHeight: any) {
|
||||
function createProjectionTF(viewportWidth, viewportHeight) {
|
||||
/*
|
||||
the projection transform accounts for the screen size & other layout
|
||||
*/
|
||||
@@ -55,7 +53,6 @@ function createProjectionTF(viewportWidth: any, viewportHeight: any) {
|
||||
0,
|
||||
(bottomGutterSizePx - topGutterSizePx) / viewportHeight / aspectScale[1],
|
||||
]);
|
||||
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number[]' is not assignable to p... Remove this comment to see the full error message
|
||||
mat3.scale(m, m, aspectScale);
|
||||
return m;
|
||||
}
|
||||
@@ -70,48 +67,32 @@ function createModelTF() {
|
||||
return m;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
type GraphState = any;
|
||||
|
||||
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
|
||||
@connect((state) => ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
annoMatrix: (state as any).annoMatrix,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
crossfilter: (state as any).obsCrossfilter,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
selectionTool: (state as any).graphSelection.tool,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
currentSelection: (state as any).graphSelection.selection,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
layoutChoice: (state as any).layoutChoice,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
graphInteractionMode: (state as any).controls.graphInteractionMode,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
colors: (state as any).colors,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
pointDilation: (state as any).pointDilation,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
genesets: (state as any).genesets.genesets,
|
||||
annoMatrix: state.annoMatrix,
|
||||
crossfilter: state.obsCrossfilter,
|
||||
selectionTool: state.graphSelection.tool,
|
||||
currentSelection: state.graphSelection.selection,
|
||||
layoutChoice: state.layoutChoice,
|
||||
graphInteractionMode: state.controls.graphInteractionMode,
|
||||
colors: state.colors,
|
||||
pointDilation: state.pointDilation,
|
||||
genesets: state.genesets.genesets,
|
||||
}))
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
class Graph extends React.Component<{}, GraphState> {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
static createReglState(canvas: any) {
|
||||
class Graph extends React.Component {
|
||||
static createReglState(canvas) {
|
||||
/*
|
||||
Must be created for each canvas
|
||||
*/
|
||||
Must be created for each canvas
|
||||
*/
|
||||
// setup canvas, webgl draw function and camera
|
||||
const camera = _camera(canvas);
|
||||
const regl = _regl(canvas);
|
||||
const drawPoints = _drawPoints(regl);
|
||||
|
||||
// preallocate webgl buffers
|
||||
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
|
||||
const pointBuffer = regl.buffer();
|
||||
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
|
||||
const colorBuffer = regl.buffer();
|
||||
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
|
||||
const flagBuffer = regl.buffer();
|
||||
|
||||
return {
|
||||
camera,
|
||||
regl,
|
||||
@@ -122,21 +103,14 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
static watchAsync(props: any, prevProps: any) {
|
||||
static watchAsync(props, prevProps) {
|
||||
return !shallowEqual(props.watchProps, prevProps.watchProps);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
cachedAsyncProps: any;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
reglCanvas: any;
|
||||
|
||||
computePointPositions = memoize((X, Y, modelTF) => {
|
||||
/*
|
||||
compute the model coordinate for each point
|
||||
*/
|
||||
compute the model coordinate for each point
|
||||
*/
|
||||
const positions = new Float32Array(2 * X.length);
|
||||
for (let i = 0, len = X.length; i < len; i += 1) {
|
||||
const p = vec2.fromValues(X[i], Y[i]);
|
||||
@@ -149,8 +123,8 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
|
||||
computePointColors = memoize((rgb) => {
|
||||
/*
|
||||
compute webgl colors for each point
|
||||
*/
|
||||
compute webgl colors for each point
|
||||
*/
|
||||
const colors = new Float32Array(3 * rgb.length);
|
||||
for (let i = 0, len = rgb.length; i < len; i += 1) {
|
||||
colors.set(rgb[i], 3 * i);
|
||||
@@ -199,20 +173,21 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
computePointFlags = memoize(
|
||||
(crossfilter, colorByData, pointDilationData, pointDilationLabel) => {
|
||||
/*
|
||||
We communicate with the shader using three flags:
|
||||
- isNaN -- the value is a NaN. Only makes sense when we have a colorAccessor
|
||||
- isSelected -- the value is selected
|
||||
- isHightlighted -- the value is highlighted in the UI (orthogonal from selection highlighting)
|
||||
|
||||
Due to constraints in webgl vertex shader attributes, these are encoded in a float, "kinda"
|
||||
like bitmasks.
|
||||
|
||||
We also have separate code paths for generating flags for categorical and
|
||||
continuous metadata, as they rely on different tests, and some of the flags
|
||||
(eg, isNaN) are meaningless in the face of categorical metadata.
|
||||
*/
|
||||
We communicate with the shader using three flags:
|
||||
- isNaN -- the value is a NaN. Only makes sense when we have a colorAccessor
|
||||
- isSelected -- the value is selected
|
||||
- isHightlighted -- the value is highlighted in the UI (orthogonal from selection highlighting)
|
||||
|
||||
Due to constraints in webgl vertex shader attributes, these are encoded in a float, "kinda"
|
||||
like bitmasks.
|
||||
|
||||
We also have separate code paths for generating flags for categorical and
|
||||
continuous metadata, as they rely on different tests, and some of the flags
|
||||
(eg, isNaN) are meaningless in the face of categorical metadata.
|
||||
*/
|
||||
const nObs = crossfilter.size();
|
||||
const flags = new Float32Array(nObs);
|
||||
|
||||
const selectedFlags = this.computeSelectedFlags(
|
||||
crossfilter,
|
||||
flagSelected,
|
||||
@@ -224,15 +199,16 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
pointDilationLabel
|
||||
);
|
||||
const colorByFlags = this.computeColorByFlags(nObs, colorByData);
|
||||
|
||||
for (let i = 0; i < nObs; i += 1) {
|
||||
flags[i] = selectedFlags[i] + highlightFlags[i] + colorByFlags[i];
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
constructor(props: {}) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const viewport = this.getViewportDimensions();
|
||||
this.reglCanvas = null;
|
||||
@@ -243,18 +219,20 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
tool: null,
|
||||
container: null,
|
||||
viewport,
|
||||
|
||||
// projection
|
||||
camera: null,
|
||||
modelTF,
|
||||
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '[]' is not assignable to paramet... Remove this comment to see the full error message
|
||||
modelInvTF: mat3.invert([], modelTF),
|
||||
projectionTF: createProjectionTF(viewport.width, viewport.height),
|
||||
|
||||
// regl state
|
||||
regl: null,
|
||||
drawPoints: null,
|
||||
pointBuffer: null,
|
||||
colorBuffer: null,
|
||||
flagBuffer: null,
|
||||
|
||||
// component rendering derived state - these must stay synchronized
|
||||
// with the reducer state they were generated from.
|
||||
layoutState: {
|
||||
@@ -273,32 +251,23 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.handleResize);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
componentDidUpdate(prevProps: {}, prevState: GraphState) {
|
||||
const {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionTool' does not exist on type 'R... Remove this comment to see the full error message
|
||||
selectionTool,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'currentSelection' does not exist on type 'R... Remove this comment to see the full error message
|
||||
currentSelection,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'graphInteractionMode' does not exist on type 'R... Remove this comment to see the full error message
|
||||
graphInteractionMode,
|
||||
} = this.props;
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { selectionTool, currentSelection, graphInteractionMode } =
|
||||
this.props;
|
||||
const { toolSVG, viewport } = this.state;
|
||||
const hasResized =
|
||||
prevState.viewport.height !== viewport.height ||
|
||||
prevState.viewport.width !== viewport.width;
|
||||
let stateChanges = {};
|
||||
|
||||
if (
|
||||
(viewport.height && viewport.width && !toolSVG) || // first time init
|
||||
hasResized || // window size has changed we want to recreate all SVGs
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionTool' does not exist on type '{... Remove this comment to see the full error message
|
||||
selectionTool !== prevProps.selectionTool || // change of selection tool
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'graphInteractionMode' does not exist on ... Remove this comment to see the full error message
|
||||
prevProps.graphInteractionMode !== graphInteractionMode // lasso/zoom mode is switched
|
||||
) {
|
||||
stateChanges = {
|
||||
@@ -306,23 +275,19 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
...this.createToolSVG(),
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
if the selection tool or state has changed, ensure that the selection
|
||||
tool correctly reflects the underlying selection.
|
||||
*/
|
||||
if the selection tool or state has changed, ensure that the selection
|
||||
tool correctly reflects the underlying selection.
|
||||
*/
|
||||
if (
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'currentSelection' does not exist on type... Remove this comment to see the full error message
|
||||
currentSelection !== prevProps.currentSelection ||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'graphInteractionMode' does not exist on ... Remove this comment to see the full error message
|
||||
graphInteractionMode !== prevProps.graphInteractionMode ||
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'toolSVG' does not exist on type '{}'.
|
||||
stateChanges.toolSVG
|
||||
) {
|
||||
const { tool, container } = this.state;
|
||||
this.selectionToolUpdate(
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'tool' does not exist on type '{}'.
|
||||
stateChanges.tool ? stateChanges.tool : tool,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'container' does not exist on type '{}'.
|
||||
stateChanges.container ? stateChanges.container : container
|
||||
);
|
||||
}
|
||||
@@ -332,12 +297,10 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.handleResize);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleResize = () => {
|
||||
const { state } = this.state;
|
||||
const viewport = this.getViewportDimensions();
|
||||
@@ -349,35 +312,27 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleCanvasEvent = (e: any) => {
|
||||
handleCanvasEvent = (e) => {
|
||||
const { camera, projectionTF } = this.state;
|
||||
if (e.type !== "wheel") e.preventDefault();
|
||||
if (camera.handleEvent(e, projectionTF)) {
|
||||
this.renderCanvas();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
this.setState((state: any) => ({
|
||||
...state,
|
||||
updateOverlay: !state.updateOverlay,
|
||||
}));
|
||||
this.setState((state) => ({ ...state, updateOverlay: !state.updateOverlay }));
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleBrushDragAction() {
|
||||
/*
|
||||
event describing brush position:
|
||||
@-------|
|
||||
| |
|
||||
| |
|
||||
|-------@
|
||||
*/
|
||||
event describing brush position:
|
||||
@-------|
|
||||
| |
|
||||
| |
|
||||
|-------@
|
||||
*/
|
||||
// ignore programatically generated events
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'event' does not exist on type 'typeof im... Remove this comment to see the full error message
|
||||
if (d3.event.sourceEvent === null || !d3.event.selection) return;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'event' does not exist on type 'typeof im... Remove this comment to see the full error message
|
||||
const s = d3.event.selection;
|
||||
const northwest = this.mapScreenToPoint(s[0]);
|
||||
const southeast = this.mapScreenToPoint(s[1]);
|
||||
@@ -395,28 +350,23 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleBrushStartAction() {
|
||||
// Ignore programatically generated events.
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'event' does not exist on type 'typeof im... Remove this comment to see the full error message
|
||||
if (!d3.event.sourceEvent) return;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
|
||||
const { dispatch } = this.props;
|
||||
dispatch(actions.graphBrushStartAction());
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleBrushEndAction() {
|
||||
// Ignore programatically generated events.
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'event' does not exist on type 'typeof im... Remove this comment to see the full error message
|
||||
if (!d3.event.sourceEvent) return;
|
||||
|
||||
/*
|
||||
coordinates will be included if selection made, null
|
||||
if selection cleared.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
coordinates will be included if selection made, null
|
||||
if selection cleared.
|
||||
*/
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'event' does not exist on type 'typeof im... Remove this comment to see the full error message
|
||||
const s = d3.event.selection;
|
||||
if (s) {
|
||||
const northwest = this.mapScreenToPoint(s[0]);
|
||||
@@ -438,27 +388,21 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleBrushDeselectAction() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
dispatch(actions.graphBrushDeselectAction(layoutChoice.current));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleLassoStart() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
|
||||
dispatch(actions.graphLassoStartAction(layoutChoice.current));
|
||||
}
|
||||
|
||||
// when a lasso is completed, filter to the points within the lasso polygon
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleLassoEnd(polygon: any) {
|
||||
handleLassoEnd(polygon) {
|
||||
const minimumPolygonArea = 10;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
|
||||
if (
|
||||
polygon.length < 3 ||
|
||||
Math.abs(d3.polygonArea(polygon)) < minimumPolygonArea
|
||||
@@ -469,38 +413,29 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
dispatch(
|
||||
actions.graphLassoEndAction(
|
||||
layoutChoice.current,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
polygon.map((xy: any) => this.mapScreenToPoint(xy))
|
||||
polygon.map((xy) => this.mapScreenToPoint(xy))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleLassoCancel() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
dispatch(actions.graphLassoCancelAction(layoutChoice.current));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleLassoDeselectAction() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch, layoutChoice } = this.props;
|
||||
dispatch(actions.graphLassoDeselectAction(layoutChoice.current));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
handleDeselectAction() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionTool' does not exist on type 'R... Remove this comment to see the full error message
|
||||
const { selectionTool } = this.props;
|
||||
if (selectionTool === "brush") this.handleBrushDeselectAction();
|
||||
if (selectionTool === "lasso") this.handleLassoDeselectAction();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleOpacityRangeChange(e: any) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
handleOpacityRangeChange(e) {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: "change opacity deselected cells in 2d graph background",
|
||||
@@ -508,17 +443,14 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
setReglCanvas = (canvas: any) => {
|
||||
setReglCanvas = (canvas) => {
|
||||
this.reglCanvas = canvas;
|
||||
this.setState({
|
||||
...Graph.createReglState(canvas),
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
getViewportDimensions = () => {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'viewportRef' does not exist on type 'Rea... Remove this comment to see the full error message
|
||||
const { viewportRef } = this.props;
|
||||
return {
|
||||
height: viewportRef.clientHeight,
|
||||
@@ -526,19 +458,19 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
};
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
createToolSVG = () => {
|
||||
/*
|
||||
Called from componentDidUpdate. Create the tool SVG, and return any
|
||||
state changes that should be passed to setState().
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionTool' does not exist on type 'R... Remove this comment to see the full error message
|
||||
Called from componentDidUpdate. Create the tool SVG, and return any
|
||||
state changes that should be passed to setState().
|
||||
*/
|
||||
const { selectionTool, graphInteractionMode } = this.props;
|
||||
const { viewport } = this.state;
|
||||
|
||||
/* clear out whatever was on the div, even if nothing, but usually the brushes etc */
|
||||
const lasso = d3.select("#lasso-layer");
|
||||
if (lasso.empty()) return {}; // still initializing
|
||||
lasso.selectAll(".lasso-group").remove();
|
||||
|
||||
// Don't render or recreate toolSVG if currently in zoom mode
|
||||
if (graphInteractionMode !== "select") {
|
||||
// don't return "change" of state unless we are really changing it!
|
||||
@@ -546,6 +478,7 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
if (toolSVG === undefined) return {};
|
||||
return { toolSVG: undefined };
|
||||
}
|
||||
|
||||
let handleStart;
|
||||
let handleDrag;
|
||||
let handleEnd;
|
||||
@@ -559,6 +492,7 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
handleEnd = this.handleLassoEnd.bind(this);
|
||||
handleCancel = this.handleLassoCancel.bind(this);
|
||||
}
|
||||
|
||||
const {
|
||||
svg: newToolSVG,
|
||||
tool,
|
||||
@@ -571,11 +505,11 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
handleCancel,
|
||||
viewport
|
||||
);
|
||||
|
||||
return { toolSVG: newToolSVG, tool, container };
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
fetchAsyncProps = async (props: any) => {
|
||||
fetchAsyncProps = async (props) => {
|
||||
const {
|
||||
annoMatrix,
|
||||
colors: colorsProp,
|
||||
@@ -585,19 +519,24 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
viewport,
|
||||
} = props.watchProps;
|
||||
const { modelTF } = this.state;
|
||||
|
||||
const [layoutDf, colorDf, pointDilationDf] = await this.fetchData(
|
||||
annoMatrix,
|
||||
layoutChoice,
|
||||
colorsProp,
|
||||
pointDilation
|
||||
);
|
||||
|
||||
const { currentDimNames } = layoutChoice;
|
||||
const X = layoutDf.col(currentDimNames[0]).asArray();
|
||||
const Y = layoutDf.col(currentDimNames[1]).asArray();
|
||||
const positions = this.computePointPositions(X, Y, modelTF);
|
||||
|
||||
const colorTable = this.updateColorTable(colorsProp, colorDf);
|
||||
const colors = this.computePointColors(colorTable.rgb);
|
||||
const colorByData = colorDf?.icol(0)?.asArray();
|
||||
|
||||
const { colorAccessor } = colorsProp;
|
||||
const colorByData = colorDf?.col(colorAccessor)?.asArray();
|
||||
const {
|
||||
metadataField: pointDilationCategory,
|
||||
categoryField: pointDilationLabel,
|
||||
@@ -611,6 +550,7 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
pointDilationData,
|
||||
pointDilationLabel
|
||||
);
|
||||
|
||||
const { width, height } = viewport;
|
||||
return {
|
||||
positions,
|
||||
@@ -621,53 +561,50 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
};
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
async fetchData(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
annoMatrix: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
layoutChoice: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
colors: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
pointDilation: any
|
||||
): Promise<[Dataframe, Dataframe | null, Dataframe | null]> {
|
||||
async fetchData(annoMatrix, layoutChoice, colors, pointDilation) {
|
||||
/*
|
||||
fetch all data needed. Includes:
|
||||
- the color by dataframe
|
||||
- the layout dataframe
|
||||
- the point dilation dataframe
|
||||
*/
|
||||
fetch all data needed. Includes:
|
||||
- the color by dataframe
|
||||
- the layout dataframe
|
||||
- the point dilation dataframe
|
||||
*/
|
||||
const { metadataField: pointDilationAccessor } = pointDilation;
|
||||
|
||||
const promises = [];
|
||||
// layout
|
||||
promises.push(annoMatrix.fetch("emb", layoutChoice.current));
|
||||
|
||||
// color
|
||||
const query = this.createColorByQuery(colors);
|
||||
const promises: [
|
||||
Promise<Dataframe>,
|
||||
Promise<Dataframe | null>,
|
||||
Promise<Dataframe | null>
|
||||
] = [
|
||||
annoMatrix.fetch("emb", layoutChoice.current),
|
||||
query ? annoMatrix.fetch(...query) : Promise.resolve(null),
|
||||
pointDilationAccessor
|
||||
? annoMatrix.fetch("obs", pointDilationAccessor)
|
||||
: Promise.resolve(null),
|
||||
];
|
||||
if (query) {
|
||||
promises.push(annoMatrix.fetch(...query));
|
||||
} else {
|
||||
promises.push(Promise.resolve(null));
|
||||
}
|
||||
|
||||
// point highlighting
|
||||
if (pointDilationAccessor) {
|
||||
promises.push(annoMatrix.fetch("obs", pointDilationAccessor));
|
||||
} else {
|
||||
promises.push(Promise.resolve(null));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
brushToolUpdate(tool: any, container: any) {
|
||||
brushToolUpdate(tool, container) {
|
||||
/*
|
||||
this is called from componentDidUpdate(), so be very careful using
|
||||
anything from this.state, which may be updated asynchronously.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'currentSelection' does not exist on type... Remove this comment to see the full error message
|
||||
this is called from componentDidUpdate(), so be very careful using
|
||||
anything from this.state, which may be updated asynchronously.
|
||||
*/
|
||||
const { currentSelection } = this.props;
|
||||
if (container) {
|
||||
const toolCurrentSelection = d3.brushSelection(container.node());
|
||||
|
||||
if (currentSelection.mode === "within-rect") {
|
||||
/*
|
||||
if there is a selection, make sure the brush tool matches
|
||||
*/
|
||||
if there is a selection, make sure the brush tool matches
|
||||
*/
|
||||
const screenCoords = [
|
||||
this.mapPointToScreen(currentSelection.brushCoords.northwest),
|
||||
this.mapPointToScreen(currentSelection.brushCoords.southeast),
|
||||
@@ -682,7 +619,6 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
for (let x = 0; x < 2; x += 1) {
|
||||
for (let y = 0; y < 2; y += 1) {
|
||||
delta += Math.abs(
|
||||
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
||||
screenCoords[x][y] - toolCurrentSelection[x][y]
|
||||
);
|
||||
}
|
||||
@@ -698,20 +634,17 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
lassoToolUpdate(tool: any) {
|
||||
lassoToolUpdate(tool) {
|
||||
/*
|
||||
this is called from componentDidUpdate(), so be very careful using
|
||||
anything from this.state, which may be updated asynchronously.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'currentSelection' does not exist on type... Remove this comment to see the full error message
|
||||
this is called from componentDidUpdate(), so be very careful using
|
||||
anything from this.state, which may be updated asynchronously.
|
||||
*/
|
||||
const { currentSelection } = this.props;
|
||||
if (currentSelection.mode === "within-polygon") {
|
||||
/*
|
||||
if there is a current selection, make sure the lasso tool matches
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const polygon = currentSelection.polygon.map((p: any) =>
|
||||
if there is a current selection, make sure the lasso tool matches
|
||||
*/
|
||||
const polygon = currentSelection.polygon.map((p) =>
|
||||
this.mapPointToScreen(p)
|
||||
);
|
||||
tool.move(polygon);
|
||||
@@ -720,20 +653,17 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
selectionToolUpdate(tool: any, container: any) {
|
||||
selectionToolUpdate(tool, container) {
|
||||
/*
|
||||
this is called from componentDidUpdate(), so be very careful using
|
||||
anything from this.state, which may be updated asynchronously.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionTool' does not exist on type 'R... Remove this comment to see the full error message
|
||||
this is called from componentDidUpdate(), so be very careful using
|
||||
anything from this.state, which may be updated asynchronously.
|
||||
*/
|
||||
const { selectionTool } = this.props;
|
||||
switch (selectionTool) {
|
||||
case "brush":
|
||||
this.brushToolUpdate(tool, container);
|
||||
break;
|
||||
case "lasso":
|
||||
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 2.
|
||||
this.lassoToolUpdate(tool, container);
|
||||
break;
|
||||
default:
|
||||
@@ -742,17 +672,19 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
mapScreenToPoint(pin: any) {
|
||||
mapScreenToPoint(pin) {
|
||||
/*
|
||||
Map an XY coordinates from screen domain to cell/point range,
|
||||
accounting for current pan/zoom camera.
|
||||
*/
|
||||
Map an XY coordinates from screen domain to cell/point range,
|
||||
accounting for current pan/zoom camera.
|
||||
*/
|
||||
|
||||
const { camera, projectionTF, modelInvTF, viewport } = this.state;
|
||||
const cameraInvTF = camera.invView();
|
||||
|
||||
/* screen -> gl */
|
||||
const x = (2 * pin[0]) / viewport.width - 1;
|
||||
const y = 2 * (1 - pin[1] / viewport.height) - 1;
|
||||
|
||||
const xy = vec2.fromValues(x, y);
|
||||
const projectionInvTF = mat3.invert(mat3.create(), projectionTF);
|
||||
vec2.transformMat3(xy, xy, projectionInvTF);
|
||||
@@ -761,17 +693,19 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
return xy;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
mapPointToScreen(xyCell: any) {
|
||||
mapPointToScreen(xyCell) {
|
||||
/*
|
||||
Map an XY coordinate from cell/point domain to screen range. Inverse
|
||||
of mapScreenToPoint()
|
||||
*/
|
||||
Map an XY coordinate from cell/point domain to screen range. Inverse
|
||||
of mapScreenToPoint()
|
||||
*/
|
||||
|
||||
const { camera, projectionTF, modelTF, viewport } = this.state;
|
||||
const cameraTF = camera.view();
|
||||
|
||||
const xy = vec2.transformMat3(vec2.create(), xyCell, modelTF);
|
||||
vec2.transformMat3(xy, xy, cameraTF);
|
||||
vec2.transformMat3(xy, xy, projectionTF);
|
||||
|
||||
return [
|
||||
Math.round(((xy[0] + 1) * viewport.width) / 2),
|
||||
Math.round(-((xy[1] + 1) / 2 - 1) * viewport.height),
|
||||
@@ -799,12 +733,12 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
updateReglAndRender(asyncProps: any, prevAsyncProps: any) {
|
||||
updateReglAndRender(asyncProps, prevAsyncProps) {
|
||||
const { positions, colors, flags, height, width } = asyncProps;
|
||||
this.cachedAsyncProps = asyncProps;
|
||||
const { pointBuffer, colorBuffer, flagBuffer } = this.state;
|
||||
let needToRenderCanvas = false;
|
||||
|
||||
if (height !== prevAsyncProps?.height || width !== prevAsyncProps?.width) {
|
||||
needToRenderCanvas = true;
|
||||
}
|
||||
@@ -823,11 +757,10 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
if (needToRenderCanvas) this.renderCanvas();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
updateColorTable(colors: any, colorDf: any) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
updateColorTable(colors, colorDf) {
|
||||
const { annoMatrix } = this.props;
|
||||
const { schema } = annoMatrix;
|
||||
|
||||
/* update color table state */
|
||||
if (!colors || !colorDf) {
|
||||
return createColorTable(
|
||||
@@ -838,6 +771,7 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
const { colorAccessor, userColors, colorMode } = colors;
|
||||
return createColorTable(
|
||||
colorMode,
|
||||
@@ -848,35 +782,26 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
createColorByQuery(colors: any) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
createColorByQuery(colors) {
|
||||
const { annoMatrix, genesets } = this.props;
|
||||
const { schema } = annoMatrix;
|
||||
const { colorMode, colorAccessor } = colors;
|
||||
|
||||
return createColorQuery(colorMode, colorAccessor, schema, genesets);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
renderPoints(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
regl: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
drawPoints: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
colorBuffer: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
pointBuffer: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
flagBuffer: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
camera: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
projectionTF: any
|
||||
regl,
|
||||
drawPoints,
|
||||
colorBuffer,
|
||||
pointBuffer,
|
||||
flagBuffer,
|
||||
camera,
|
||||
projectionTF
|
||||
) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
const { annoMatrix } = this.props;
|
||||
if (!this.reglCanvas || !annoMatrix) return;
|
||||
|
||||
const { schema } = annoMatrix;
|
||||
const cameraTF = camera.view();
|
||||
const projView = mat3.multiply(mat3.create(), projectionTF, cameraTF);
|
||||
@@ -899,24 +824,18 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
regl._gl.flush();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
render() {
|
||||
const {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'graphInteractionMode' does not exist on ... Remove this comment to see the full error message
|
||||
graphInteractionMode,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on ... Remove this comment to see the full error message
|
||||
annoMatrix,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colors' does not exist on ... Remove this comment to see the full error message
|
||||
colors,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'layoutChoice' does not exist on ... Remove this comment to see the full error message
|
||||
layoutChoice,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'pointDilation' does not exist on ... Remove this comment to see the full error message
|
||||
pointDilation,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'crossfilter' does not exist on ... Remove this comment to see the full error message
|
||||
crossfilter,
|
||||
} = this.props;
|
||||
const { modelTF, projectionTF, camera, viewport, regl } = this.state;
|
||||
const cameraTF = camera?.view()?.slice();
|
||||
|
||||
return (
|
||||
<div
|
||||
id="graph-wrapper"
|
||||
@@ -927,7 +846,6 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}}
|
||||
>
|
||||
<GraphOverlayLayer
|
||||
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element; width: any; height: any... Remove this comment to see the full error message
|
||||
width={viewport.width}
|
||||
height={viewport.height}
|
||||
cameraTF={cameraTF}
|
||||
@@ -987,7 +905,6 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}}
|
||||
>
|
||||
<Async.Pending initial>
|
||||
{/* eslint-disable-next-line @typescript-eslint/no-use-before-define --- StillLoading used before defined */}
|
||||
<StillLoading
|
||||
displayName={layoutChoice.current}
|
||||
width={viewport.width}
|
||||
@@ -996,7 +913,6 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
</Async.Pending>
|
||||
<Async.Rejected>
|
||||
{(error) => (
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define --- ErrorLoading used before defined
|
||||
<ErrorLoading
|
||||
displayName={layoutChoice.current}
|
||||
error={error}
|
||||
@@ -1019,8 +935,7 @@ class Graph extends React.Component<{}, GraphState> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const ErrorLoading = ({ displayName, error, width, height }: any) => {
|
||||
const ErrorLoading = ({ displayName, error, width, height }) => {
|
||||
console.log(error); // log to console as this is an unepected error
|
||||
return (
|
||||
<div
|
||||
@@ -1036,30 +951,32 @@ const ErrorLoading = ({ displayName, error, width, height }: any) => {
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const StillLoading = ({ displayName, width, height }: any) => (
|
||||
const StillLoading = ({ displayName, width, height }) =>
|
||||
/*
|
||||
Render a busy/loading indicator
|
||||
*/
|
||||
<div
|
||||
style={{
|
||||
position: "fixed",
|
||||
fontWeight: 500,
|
||||
top: height / 2,
|
||||
width,
|
||||
}}
|
||||
>
|
||||
(
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
justifyItems: "center",
|
||||
alignItems: "center",
|
||||
position: "fixed",
|
||||
fontWeight: 500,
|
||||
top: height / 2,
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<Button minimal loading intent="primary" />
|
||||
<span style={{ fontStyle: "italic" }}>Loading {displayName}</span>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
justifyItems: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Button minimal loading intent="primary" />
|
||||
<span style={{ fontStyle: "italic" }}>Loading {displayName}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
;
|
||||
|
||||
export default Graph;
|
||||
@@ -0,0 +1,218 @@
|
||||
import React, { PureComponent } from "react";
|
||||
import { connect, shallowEqual } from "react-redux";
|
||||
import Async from "react-async";
|
||||
|
||||
import { categoryLabelDisplayStringLongLength } from "../../../globals";
|
||||
import calcCentroid from "../../../util/centroid";
|
||||
import { createColorQuery } from "../../../util/stateManager/colorHelpers";
|
||||
|
||||
export default
|
||||
@connect((state) => ({
|
||||
annoMatrix: state.annoMatrix,
|
||||
colors: state.colors,
|
||||
layoutChoice: state.layoutChoice,
|
||||
dilatedValue: state.pointDilation.categoryField,
|
||||
categoricalSelection: state.categoricalSelection,
|
||||
showLabels: state.centroidLabels?.showLabels,
|
||||
genesets: state.genesets.genesets,
|
||||
}))
|
||||
class CentroidLabels extends PureComponent {
|
||||
static watchAsync(props, prevProps) {
|
||||
return !shallowEqual(props.watchProps, prevProps.watchProps);
|
||||
}
|
||||
|
||||
fetchAsyncProps = async (props) => {
|
||||
const {
|
||||
annoMatrix,
|
||||
colors,
|
||||
layoutChoice,
|
||||
categoricalSelection,
|
||||
showLabels,
|
||||
} = props.watchProps;
|
||||
const { schema } = annoMatrix;
|
||||
const { colorAccessor } = colors;
|
||||
|
||||
const [layoutDf, colorDf] = await this.fetchData();
|
||||
let labels;
|
||||
if (colorDf) {
|
||||
labels = calcCentroid(
|
||||
schema,
|
||||
colorAccessor,
|
||||
colorDf,
|
||||
layoutChoice,
|
||||
layoutDf
|
||||
);
|
||||
} else {
|
||||
labels = new Map();
|
||||
}
|
||||
|
||||
const { overlaySetShowing } = this.props;
|
||||
overlaySetShowing("centroidLabels", showLabels && labels.size > 0);
|
||||
|
||||
return {
|
||||
labels,
|
||||
colorAccessor,
|
||||
category: categoricalSelection[colorAccessor],
|
||||
};
|
||||
};
|
||||
|
||||
handleMouseEnter = (e, colorAccessor, label) => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: "category value mouse hover start",
|
||||
metadataField: colorAccessor,
|
||||
categoryField: label,
|
||||
});
|
||||
};
|
||||
|
||||
handleMouseOut = (e, colorAccessor, label) => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: "category value mouse hover end",
|
||||
metadataField: colorAccessor,
|
||||
categoryField: label,
|
||||
});
|
||||
};
|
||||
|
||||
colorByQuery() {
|
||||
const { annoMatrix, colors, genesets } = this.props;
|
||||
const { schema } = annoMatrix;
|
||||
const { colorMode, colorAccessor } = colors;
|
||||
return createColorQuery(colorMode, colorAccessor, schema, genesets);
|
||||
}
|
||||
|
||||
async fetchData() {
|
||||
const { annoMatrix, layoutChoice } = this.props;
|
||||
// fetch all data we need: layout, category
|
||||
const promises = [];
|
||||
// layout
|
||||
promises.push(annoMatrix.fetch("emb", layoutChoice.current));
|
||||
// category to label - we ONLY label on obs, never on X, etc.
|
||||
const query = this.colorByQuery();
|
||||
if (query && query[0] === "obs") {
|
||||
promises.push(annoMatrix.fetch(...query));
|
||||
} else {
|
||||
promises.push(Promise.resolve(null));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
inverseTransform,
|
||||
dilatedValue,
|
||||
categoricalSelection,
|
||||
showLabels,
|
||||
colors,
|
||||
annoMatrix,
|
||||
layoutChoice,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Async
|
||||
watchFn={CentroidLabels.watchAsync}
|
||||
promiseFn={this.fetchAsyncProps}
|
||||
watchProps={{
|
||||
annoMatrix,
|
||||
colors,
|
||||
layoutChoice,
|
||||
categoricalSelection,
|
||||
dilatedValue,
|
||||
showLabels,
|
||||
}}
|
||||
>
|
||||
<Async.Fulfilled>
|
||||
{(asyncProps) => {
|
||||
if (!showLabels) return null;
|
||||
|
||||
const labelSVGS = [];
|
||||
const deselectOpacity = 0.375;
|
||||
const { category, colorAccessor, labels } = asyncProps;
|
||||
|
||||
labels.forEach((coords, label) => {
|
||||
const selected = category.get(label) ?? true;
|
||||
|
||||
// Mirror LSB middle truncation
|
||||
let displayLabel = label;
|
||||
if (displayLabel.length > categoryLabelDisplayStringLongLength) {
|
||||
displayLabel = `${label.slice(
|
||||
0,
|
||||
categoryLabelDisplayStringLongLength / 2
|
||||
)}…${label.slice(-categoryLabelDisplayStringLongLength / 2)}`;
|
||||
}
|
||||
|
||||
labelSVGS.push(
|
||||
// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events -- the mouse actions for centroid labels do not have a screen reader alternative
|
||||
<Label
|
||||
key={label} // eslint-disable-line react/no-array-index-key --- label is not an index, eslint is confused
|
||||
label={label}
|
||||
dilatedValue={dilatedValue}
|
||||
coords={coords}
|
||||
inverseTransform={inverseTransform}
|
||||
opactity={selected ? 1 : deselectOpacity}
|
||||
colorAccessor={colorAccessor}
|
||||
displayLabel={displayLabel}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseOut={this.handleMouseOut}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return <>{labelSVGS}</>;
|
||||
}}
|
||||
</Async.Fulfilled>
|
||||
</Async>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const Label = ({
|
||||
label,
|
||||
dilatedValue,
|
||||
coords,
|
||||
inverseTransform,
|
||||
opacity,
|
||||
colorAccessor,
|
||||
displayLabel,
|
||||
onMouseEnter,
|
||||
onMouseOut,
|
||||
}) => {
|
||||
/*
|
||||
Render a label at a given coordinate.
|
||||
*/
|
||||
let fontSize = "15px";
|
||||
let fontWeight = null;
|
||||
if (label === dilatedValue) {
|
||||
fontSize = "18px";
|
||||
fontWeight = "800";
|
||||
}
|
||||
|
||||
return (
|
||||
<g
|
||||
key={label}
|
||||
className="centroid-label"
|
||||
transform={`translate(${coords[0]}, ${coords[1]})`}
|
||||
data-testclass="centroid-label"
|
||||
data-testid={`${label}-centroid-label`}
|
||||
>
|
||||
{/* eslint-disable-next-line jsx-a11y/mouse-events-have-key-events --- the mouse actions for centroid labels do not have a screen reader alternative*/}
|
||||
<text
|
||||
transform={inverseTransform}
|
||||
textAnchor="middle"
|
||||
style={{
|
||||
fontSize,
|
||||
fontWeight,
|
||||
fill: "black",
|
||||
userSelect: "none",
|
||||
opacity: { opacity },
|
||||
}}
|
||||
onMouseEnter={(e) => onMouseEnter(e, colorAccessor, label)}
|
||||
onMouseOut={(e) => onMouseOut(e, colorAccessor, label)}
|
||||
pointerEvents="visiblePainted"
|
||||
>
|
||||
{displayLabel}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
};
|
||||
@@ -1,241 +0,0 @@
|
||||
import React, { PureComponent } from "react";
|
||||
import { connect, shallowEqual } from "react-redux";
|
||||
import Async from "react-async";
|
||||
|
||||
import { categoryLabelDisplayStringLongLength } from "../../../globals";
|
||||
import calcCentroid from "../../../util/centroid";
|
||||
import { createColorQuery } from "../../../util/stateManager/colorHelpers";
|
||||
|
||||
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
|
||||
@connect((state) => ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
annoMatrix: (state as any).annoMatrix,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
colors: (state as any).colors,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
layoutChoice: (state as any).layoutChoice,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
dilatedValue: (state as any).pointDilation.categoryField,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
categoricalSelection: (state as any).categoricalSelection,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
showLabels: (state as any).centroidLabels?.showLabels,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
genesets: (state as any).genesets.genesets,
|
||||
}))
|
||||
export default class CentroidLabels extends PureComponent {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
static watchAsync(props: any, prevProps: any) {
|
||||
return !shallowEqual(props.watchProps, prevProps.watchProps);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
fetchAsyncProps = async (props: any) => {
|
||||
const {
|
||||
annoMatrix,
|
||||
colors,
|
||||
layoutChoice,
|
||||
categoricalSelection,
|
||||
showLabels,
|
||||
} = props.watchProps;
|
||||
const { schema } = annoMatrix;
|
||||
const { colorAccessor } = colors;
|
||||
const [layoutDf, colorDf] = await this.fetchData();
|
||||
let labels;
|
||||
if (colorDf) {
|
||||
labels = calcCentroid(
|
||||
schema,
|
||||
colorAccessor,
|
||||
colorDf,
|
||||
layoutChoice,
|
||||
layoutDf
|
||||
);
|
||||
} else {
|
||||
labels = new Map();
|
||||
}
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'overlaySetShowing' does not exist on typ... Remove this comment to see the full error message
|
||||
const { overlaySetShowing } = this.props;
|
||||
overlaySetShowing("centroidLabels", showLabels && labels.size > 0);
|
||||
return {
|
||||
labels,
|
||||
colorAccessor,
|
||||
category: categoricalSelection[colorAccessor],
|
||||
};
|
||||
};
|
||||
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'e' is declared but its value is never read.
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleMouseEnter = (e: any, colorAccessor: any, label: any) => {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: "category value mouse hover start",
|
||||
metadataField: colorAccessor,
|
||||
categoryField: label,
|
||||
});
|
||||
};
|
||||
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'e' is declared but its value is never read.
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleMouseOut = (e: any, colorAccessor: any, label: any) => {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: "category value mouse hover end",
|
||||
metadataField: colorAccessor,
|
||||
categoryField: label,
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
colorByQuery() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
const { annoMatrix, colors, genesets } = this.props;
|
||||
const { schema } = annoMatrix;
|
||||
const { colorMode, colorAccessor } = colors;
|
||||
return createColorQuery(colorMode, colorAccessor, schema, genesets);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
async fetchData() {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
const { annoMatrix, layoutChoice } = this.props;
|
||||
// fetch all data we need: layout, category
|
||||
const promises = [];
|
||||
// layout
|
||||
promises.push(annoMatrix.fetch("emb", layoutChoice.current));
|
||||
// category to label - we ONLY label on obs, never on X, etc.
|
||||
const query = this.colorByQuery();
|
||||
if (query && query[0] === "obs") {
|
||||
promises.push(annoMatrix.fetch(...query));
|
||||
} else {
|
||||
promises.push(Promise.resolve(null));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
render() {
|
||||
const {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'inverseTransform' does not exist on type... Remove this comment to see the full error message
|
||||
inverseTransform,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dilatedValue' does not exist on type 'Re... Remove this comment to see the full error message
|
||||
dilatedValue,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoricalSelection' does not exist on ... Remove this comment to see the full error message
|
||||
categoricalSelection,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'showLabels' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
showLabels,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colors' does not exist on type 'Readonly... Remove this comment to see the full error message
|
||||
colors,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
|
||||
annoMatrix,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'layoutChoice' does not exist on type 'Re... Remove this comment to see the full error message
|
||||
layoutChoice,
|
||||
} = this.props;
|
||||
return (
|
||||
<Async
|
||||
watchFn={CentroidLabels.watchAsync}
|
||||
promiseFn={this.fetchAsyncProps}
|
||||
watchProps={{
|
||||
annoMatrix,
|
||||
colors,
|
||||
layoutChoice,
|
||||
categoricalSelection,
|
||||
dilatedValue,
|
||||
showLabels,
|
||||
}}
|
||||
>
|
||||
<Async.Fulfilled>
|
||||
{(asyncProps) => {
|
||||
if (!showLabels) return null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const labelSVGS: any = [];
|
||||
const deselectOpacity = 0.375;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'category' does not exist on type 'unknow... Remove this comment to see the full error message
|
||||
const { category, colorAccessor, labels } = asyncProps;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
labels.forEach((coords: any, label: any) => {
|
||||
const selected = category.get(label) ?? true;
|
||||
// Mirror LSB middle truncation
|
||||
let displayLabel = label;
|
||||
if (displayLabel.length > categoryLabelDisplayStringLongLength) {
|
||||
displayLabel = `${label.slice(
|
||||
0,
|
||||
categoryLabelDisplayStringLongLength / 2
|
||||
)}…${label.slice(-categoryLabelDisplayStringLongLength / 2)}`;
|
||||
}
|
||||
labelSVGS.push(
|
||||
// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events -- the mouse actions for centroid labels do not have a screen reader alternative
|
||||
<Label
|
||||
key={label} // eslint-disable-line react/no-array-index-key --- label is not an index, eslint is confused
|
||||
label={label}
|
||||
dilatedValue={dilatedValue}
|
||||
coords={coords}
|
||||
inverseTransform={inverseTransform}
|
||||
opactity={selected ? 1 : deselectOpacity}
|
||||
colorAccessor={colorAccessor}
|
||||
displayLabel={displayLabel}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseOut={this.handleMouseOut}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return <>{labelSVGS}</>;
|
||||
}}
|
||||
</Async.Fulfilled>
|
||||
</Async>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const Label = ({
|
||||
label,
|
||||
dilatedValue,
|
||||
coords,
|
||||
inverseTransform,
|
||||
opacity,
|
||||
colorAccessor,
|
||||
displayLabel,
|
||||
onMouseEnter,
|
||||
onMouseOut, // eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
}: any) => {
|
||||
/*
|
||||
Render a label at a given coordinate.
|
||||
*/
|
||||
let fontSize = "15px";
|
||||
let fontWeight = null;
|
||||
if (label === dilatedValue) {
|
||||
fontSize = "18px";
|
||||
fontWeight = "800";
|
||||
}
|
||||
|
||||
return (
|
||||
<g
|
||||
key={label}
|
||||
className="centroid-label"
|
||||
transform={`translate(${coords[0]}, ${coords[1]})`}
|
||||
data-testclass="centroid-label"
|
||||
data-testid={`${label}-centroid-label`}
|
||||
>
|
||||
{/* eslint-disable-next-line jsx-a11y/mouse-events-have-key-events --- the mouse actions for centroid labels do not have a screen reader alternative*/}
|
||||
<text
|
||||
transform={inverseTransform}
|
||||
textAnchor="middle"
|
||||
style={{
|
||||
fontSize,
|
||||
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string | null' is not assignable to type 'Fo... Remove this comment to see the full error message
|
||||
fontWeight,
|
||||
fill: "black",
|
||||
userSelect: "none",
|
||||
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ opacity: any; }' is not assignable to type... Remove this comment to see the full error message
|
||||
opacity: { opacity },
|
||||
}}
|
||||
onMouseEnter={(e) => onMouseEnter(e, colorAccessor, label)}
|
||||
onMouseOut={(e) => onMouseOut(e, colorAccessor, label)}
|
||||
pointerEvents="visiblePainted"
|
||||
>
|
||||
{displayLabel}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
};
|
||||
+8
-29
@@ -1,29 +1,22 @@
|
||||
import React, { PureComponent, cloneElement } from "react";
|
||||
|
||||
// @ts-expect-error ts-migrate(2307) FIXME: Cannot find module '../graph.css' or its correspon... Remove this comment to see the full error message
|
||||
import styles from "../graph.css";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
type State = any;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
export default class GraphOverlayLayer extends PureComponent<{}, State> {
|
||||
export default class GraphOverlayLayer extends PureComponent {
|
||||
/*
|
||||
This component takes its children (assumed in the data coordinate space ([0, 1] range, origin in bottom left corner))
|
||||
and transforms itself multiple times resulting in screen space ([0, screenWidth/Height] range, origin in top left corner)
|
||||
|
||||
Children are assigned in the graph component and must implement onDisplayChange()
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
constructor(props: {}) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
display: {},
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
matrixToTransformString = (m: any) =>
|
||||
matrixToTransformString = (m) =>
|
||||
/*
|
||||
Translates the gl-matrix mat3 to SVG matrix transform style
|
||||
|
||||
@@ -32,37 +25,24 @@ export default class GraphOverlayLayer extends PureComponent<{}, State> {
|
||||
b d f / [a, b, 0, c, d, 0, e, f, 1] => matrix(a, b, c, d, e, f) / matrix(sx, 0, 0, sy, tx, ty) / matrix(m[0] m[3] m[1] m[4] m[6] m[7])
|
||||
0 0 1
|
||||
*/
|
||||
`matrix(${m[0]} ${m[1]} ${m[3]} ${m[4]} ${m[6]} ${m[7]})`;
|
||||
`matrix(${m[0]} ${m[1]} ${m[3]} ${m[4]} ${m[6]} ${m[7]})`
|
||||
;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
reverseMatrixScaleTransformString = (m: any) =>
|
||||
`matrix(${1 / m[0]} 0 0 ${1 / m[4]} 0 0)`;
|
||||
reverseMatrixScaleTransformString = (m) => `matrix(${1 / m[0]} 0 0 ${1 / m[4]} 0 0)`;
|
||||
|
||||
// This is passed to all children, should be called when an overlay's display state is toggled along with the overlay name and its new display state in boolean form
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
overlaySetShowing = (overlay: any, displaying: any) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
this.setState((state: any) => ({
|
||||
...state,
|
||||
display: { ...state.display, [overlay]: displaying },
|
||||
}));
|
||||
overlaySetShowing = (overlay, displaying) => {
|
||||
this.setState((state) => ({ ...state, display: { ...state.display, [overlay]: displaying } }));
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
render() {
|
||||
const {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'cameraTF' does not exist on type 'Readon... Remove this comment to see the full error message
|
||||
cameraTF,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'modelTF' does not exist on type 'Readonl... Remove this comment to see the full error message
|
||||
modelTF,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'projectionTF' does not exist on type 'Re... Remove this comment to see the full error message
|
||||
projectionTF,
|
||||
children,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'handleCanvasEvent' does not exist on typ... Remove this comment to see the full error message
|
||||
handleCanvasEvent,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'width' does not exist on type 'Readonly<... Remove this comment to see the full error message
|
||||
width,
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'height' does not exist on type 'Readonly... Remove this comment to see the full error message
|
||||
height,
|
||||
} = this.props;
|
||||
const { display } = this.state;
|
||||
@@ -81,7 +61,6 @@ export default class GraphOverlayLayer extends PureComponent<{}, State> {
|
||||
|
||||
// Copy the children passed with the overlay and add the inverse transform and onDisplayChange props
|
||||
const newChildren = React.Children.map(children, (child) =>
|
||||
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
|
||||
cloneElement(child, {
|
||||
inverseTransform,
|
||||
overlaySetShowing: this.overlaySetShowing,
|
||||
+16
-31
@@ -1,28 +1,19 @@
|
||||
import * as d3 from "d3";
|
||||
import { Colors } from "@blueprintjs/core";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
const Lasso = () => {
|
||||
const dispatch = d3.dispatch("start", "end", "cancel");
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const lasso = (svg: any) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
let lassoPolygon: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
let lassoPath: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
let closePath: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
let lassoInProgress: any;
|
||||
const lasso = (svg) => {
|
||||
let lassoPolygon;
|
||||
let lassoPath;
|
||||
let closePath;
|
||||
let lassoInProgress;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const polygonToPath = (polygon: any) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
`M${polygon.map((d: any) => d.join(",")).join("L")}`;
|
||||
const polygonToPath = (polygon) =>
|
||||
`M${polygon.map((d) => d.join(",")).join("L")}`;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const distance = (pt1: any, pt2: any) =>
|
||||
const distance = (pt1, pt2) =>
|
||||
Math.sqrt((pt2[0] - pt1[0]) ** 2 + (pt2[1] - pt1[1]) ** 2);
|
||||
|
||||
// distance last point has to be to first point before it auto closes when mouse is released
|
||||
@@ -30,14 +21,12 @@ const Lasso = () => {
|
||||
const lassoPathColor = Colors.BLUE5;
|
||||
|
||||
const handleDragStart = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
lassoPolygon = [(d3 as any).mouse(svg.node())]; // current x y of mouse within element
|
||||
lassoPolygon = [d3.mouse(svg.node())]; // current x y of mouse within element
|
||||
|
||||
if (lassoPath) {
|
||||
// If the existing path is in progress
|
||||
if (lassoInProgress) {
|
||||
// cancel the existing lasso
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define --- handleCancel used before defined
|
||||
handleCancel();
|
||||
// Don't continue with current drag start
|
||||
return;
|
||||
@@ -48,14 +37,12 @@ const Lasso = () => {
|
||||
// We're starting a new drag
|
||||
lassoInProgress = true;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define --- g used before defined
|
||||
lassoPath = g
|
||||
.append("path")
|
||||
.attr("data-testid", "lasso-element")
|
||||
.attr("fill-opacity", 0.1)
|
||||
.attr("stroke-dasharray", "3, 3");
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define --- g used before defined
|
||||
closePath = g
|
||||
.append("line")
|
||||
.attr("x2", lassoPolygon[0][0])
|
||||
@@ -66,8 +53,7 @@ const Lasso = () => {
|
||||
};
|
||||
|
||||
const handleDrag = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const point = (d3 as any).mouse(svg.node());
|
||||
const point = d3.mouse(svg.node());
|
||||
lassoPolygon.push(point);
|
||||
lassoPath.attr("d", polygonToPath(lassoPolygon));
|
||||
|
||||
@@ -137,12 +123,12 @@ const Lasso = () => {
|
||||
|
||||
area.call(drag);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
(lasso as any).reset = () => {
|
||||
lasso.reset = () => {
|
||||
if (lassoPath) {
|
||||
lassoPath.remove();
|
||||
lassoPath = null;
|
||||
}
|
||||
|
||||
lassoPolygon = null;
|
||||
if (closePath) {
|
||||
closePath.remove();
|
||||
@@ -150,11 +136,10 @@ const Lasso = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
(lasso as any).move = (polygon: any) => {
|
||||
lasso.move = (polygon) => {
|
||||
if (polygon !== lassoPolygon || polygon.length !== lassoPolygon.length) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'reset' does not exist on type '(svg: any... Remove this comment to see the full error message
|
||||
lasso.reset();
|
||||
|
||||
lassoPolygon = polygon;
|
||||
lassoPath = g
|
||||
.append("path")
|
||||
@@ -163,13 +148,13 @@ const Lasso = () => {
|
||||
.attr("fill-opacity", 0.1)
|
||||
.attr("stroke", lassoPathColor)
|
||||
.attr("stroke-dasharray", "3, 3");
|
||||
|
||||
lassoPath.attr("d", `${polygonToPath(lassoPolygon)}Z`);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
lasso.on = (type: any, callback: any) => {
|
||||
lasso.on = (type, callback) => {
|
||||
dispatch.on(type, callback);
|
||||
return lasso;
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
import * as d3 from "d3";
|
||||
import Lasso from "./setupLasso";
|
||||
|
||||
/******************************************
|
||||
*******************************************
|
||||
put svg & brush in DOM
|
||||
*******************************************
|
||||
******************************************/
|
||||
|
||||
export default (
|
||||
selectionToolType,
|
||||
handleStartAction,
|
||||
handleDragAction,
|
||||
handleEndAction,
|
||||
handleCancelAction,
|
||||
viewport
|
||||
) => {
|
||||
const svg = d3.select("#graph-wrapper").select("#lasso-layer");
|
||||
if (svg.empty()) return {};
|
||||
|
||||
if (selectionToolType === "brush") {
|
||||
const brush = d3
|
||||
.brush()
|
||||
.extent([
|
||||
[0, 0],
|
||||
[viewport.width, viewport.height],
|
||||
])
|
||||
.on("start", handleStartAction)
|
||||
.on("brush", handleDragAction)
|
||||
// FYI, brush doesn't generate cancel
|
||||
.on("end", handleEndAction);
|
||||
|
||||
const brushContainer = svg
|
||||
.append("g")
|
||||
.attr("class", "graph_brush")
|
||||
.call(brush);
|
||||
|
||||
return { svg, container: brushContainer, tool: brush };
|
||||
}
|
||||
|
||||
if (selectionToolType === "lasso") {
|
||||
const lasso = Lasso()
|
||||
.on("end", handleEndAction)
|
||||
// FYI, Lasso doesn't generate drag
|
||||
.on("start", handleStartAction)
|
||||
.on("cancel", handleCancelAction);
|
||||
|
||||
const lassoContainer = svg.call(lasso);
|
||||
|
||||
return { svg, container: lassoContainer, tool: lasso };
|
||||
}
|
||||
|
||||
throw new Error("unknown graph selection tool");
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
import * as d3 from "d3";
|
||||
import Lasso from "./setupLasso";
|
||||
|
||||
/******************************************
|
||||
*******************************************
|
||||
put svg & brush in DOM
|
||||
*******************************************
|
||||
******************************************/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
|
||||
export default (
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
selectionToolType: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleStartAction: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleDragAction: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleEndAction: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
handleCancelAction: any,
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
viewport: any
|
||||
) => {
|
||||
const svg = d3.select("#graph-wrapper").select("#lasso-layer");
|
||||
if (svg.empty()) return {};
|
||||
|
||||
if (selectionToolType === "brush") {
|
||||
const brush = d3
|
||||
.brush()
|
||||
.extent([
|
||||
[0, 0],
|
||||
[viewport.width, viewport.height],
|
||||
])
|
||||
.on("start", handleStartAction)
|
||||
.on("brush", handleDragAction)
|
||||
// FYI, brush doesn't generate cancel
|
||||
.on("end", handleEndAction);
|
||||
|
||||
const brushContainer = svg
|
||||
.append("g")
|
||||
.attr("class", "graph_brush")
|
||||
.call(brush);
|
||||
|
||||
return { svg, container: brushContainer, tool: brush };
|
||||
}
|
||||
|
||||
if (selectionToolType === "lasso") {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
const lasso = (Lasso() as any)
|
||||
.on("end", handleEndAction)
|
||||
// FYI, Lasso doesn't generate drag
|
||||
.on("start", handleStartAction)
|
||||
.on("cancel", handleCancelAction);
|
||||
|
||||
const lassoContainer = svg.call(lasso);
|
||||
|
||||
return { svg, container: lassoContainer, tool: lasso };
|
||||
}
|
||||
|
||||
throw new Error("unknown graph selection tool");
|
||||
};
|
||||
Reference in New Issue
Block a user