mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-02 02:48:11 +08:00
reset brush on window resize
This commit is contained in:
@@ -3,7 +3,7 @@ import React from "react";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import * as globals from "../../globals";
|
import * as globals from "../../globals";
|
||||||
import styles from "./graph.css";
|
import styles from "./graph.css";
|
||||||
import { setupGraphElements } from "./drawGraph";
|
import { setupSVGandBrushElements } from "./setupSVGandBrush";
|
||||||
import SectionHeader from "../framework/sectionHeader";
|
import SectionHeader from "../framework/sectionHeader";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import actions from "../../actions";
|
import actions from "../../actions";
|
||||||
@@ -64,12 +64,6 @@ class Graph extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { svg } = setupGraphElements(
|
|
||||||
this.handleBrushSelectAction.bind(this),
|
|
||||||
this.handleBrushDeselectAction.bind(this)
|
|
||||||
);
|
|
||||||
this.setState({ svg });
|
|
||||||
|
|
||||||
// setup canvas and camera
|
// setup canvas and camera
|
||||||
const camera = _camera(this.reglCanvas, { scale: true, rotate: false });
|
const camera = _camera(this.reglCanvas, { scale: true, rotate: false });
|
||||||
const regl = _regl(this.reglCanvas);
|
const regl = _regl(this.reglCanvas);
|
||||||
@@ -111,49 +105,61 @@ class Graph extends React.Component {
|
|||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if (this.state.regl && nextProps.vertices) {
|
if (this.state.regl && nextProps.vertices) {
|
||||||
|
/* update regl */
|
||||||
const vertices = nextProps.currentCellSelection;
|
const vertices = nextProps.currentCellSelection;
|
||||||
const vertexCount = vertices.length;
|
const vertexCount = vertices.length;
|
||||||
|
const positions = new Float32Array(2 * vertexCount);
|
||||||
const colors = new Float32Array(3 * vertexCount);
|
const colors = new Float32Array(3 * vertexCount);
|
||||||
const sizes = new Float32Array(vertexCount);
|
const sizes = new Float32Array(vertexCount);
|
||||||
|
|
||||||
// Cache a scaled graph
|
// d3.scaleLinear().domain([0,1]).range([-1,1])
|
||||||
if (!this.scaledGraphVec || this.props.graphVec !== nextProps.graphVec) {
|
const glScaleX = scaleLinear([0, 1], [-1, 1]);
|
||||||
const positions = new Float32Array(2 * vertexCount);
|
// d3.scaleLinear().domain([0,1]).range([1,-1])
|
||||||
|
const glScaleY = scaleLinear([0, 1], [1, -1]);
|
||||||
// d3.scaleLinear().domain([0,1]).range([-1,1])
|
|
||||||
const glScaleX = scaleLinear([0, 1], [-1, 1]);
|
|
||||||
// d3.scaleLinear().domain([0,1]).range([1,-1])
|
|
||||||
const glScaleY = scaleLinear([0, 1], [1, -1]);
|
|
||||||
|
|
||||||
const graphVec = nextProps.graphVec;
|
|
||||||
for (var i = 0; i < vertexCount; i++) {
|
|
||||||
const cell = vertices[i];
|
|
||||||
const cellIdx = cell.__cellIndex__;
|
|
||||||
|
|
||||||
const x = glScaleX(graphVec[2 * cellIdx]);
|
|
||||||
const y = glScaleY(graphVec[2 * cellIdx + 1]);
|
|
||||||
positions[2 * i] = x;
|
|
||||||
positions[2 * i + 1] = y;
|
|
||||||
}
|
|
||||||
this.scaledGraphVec = positions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Construct Size & Color Vectors
|
Construct Vectors
|
||||||
*/
|
*/
|
||||||
|
const graphVec = nextProps.graphVec;
|
||||||
for (var i = 0; i < vertexCount; i++) {
|
for (var i = 0; i < vertexCount; i++) {
|
||||||
const cell = vertices[i];
|
const cell = vertices[i];
|
||||||
|
const cellIdx = cell.__cellIndex__;
|
||||||
|
const x = glScaleX(graphVec[2 * cellIdx]);
|
||||||
|
const y = glScaleY(graphVec[2 * cellIdx + 1]);
|
||||||
|
positions[2 * i] = x;
|
||||||
|
positions[2 * i + 1] = y;
|
||||||
|
|
||||||
colors.set(cell.__colorRGB__, 3 * i);
|
colors.set(cell.__colorRGB__, 3 * i);
|
||||||
|
|
||||||
sizes[i] = cell.__selected__
|
sizes[i] = cell.__selected__
|
||||||
? 4
|
? 4
|
||||||
: 0.2; /* make this a function of the number of total cells, including regraph */
|
: 0.2; /* make this a function of the number of total cells, including regraph */
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state.pointBuffer({ data: this.scaledGraphVec, dimension: 2 });
|
this.state.pointBuffer({ data: positions, dimension: 2 });
|
||||||
this.state.colorBuffer({ data: colors, dimension: 3 });
|
this.state.colorBuffer({ data: colors, dimension: 3 });
|
||||||
this.state.sizeBuffer({ data: sizes, dimension: 1 });
|
this.state.sizeBuffer({ data: sizes, dimension: 1 });
|
||||||
this.count = vertexCount;
|
this.count = vertexCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
/* invisibly handles the initial null vs integer case as well as resize events */
|
||||||
|
nextProps.responsive.height !== this.props.responsive.height ||
|
||||||
|
nextProps.responsive.width !== this.props.responsive.width
|
||||||
|
) {
|
||||||
|
/* clear out whatever was on the div, even if nothing, but usually the brushes etc */
|
||||||
|
d3
|
||||||
|
.select("#graphAttachPoint")
|
||||||
|
.selectAll("*")
|
||||||
|
.remove();
|
||||||
|
const { svg } = setupSVGandBrushElements(
|
||||||
|
this.handleBrushSelectAction.bind(this),
|
||||||
|
this.handleBrushDeselectAction.bind(this),
|
||||||
|
nextProps.responsive,
|
||||||
|
this.graphPaddingTop
|
||||||
|
);
|
||||||
|
this.setState({ svg });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
handleBrushSelectAction() {
|
handleBrushSelectAction() {
|
||||||
/*
|
/*
|
||||||
@@ -176,8 +182,12 @@ class Graph extends React.Component {
|
|||||||
|
|
||||||
// transform screen coordinates -> cell coordinates
|
// transform screen coordinates -> cell coordinates
|
||||||
const invert = pin => {
|
const invert = pin => {
|
||||||
const x = 2 * pin[0] / globals.graphWidth - 1;
|
const x =
|
||||||
const y = 2 * (1 - pin[1] / globals.graphHeight) - 1;
|
2 * pin[0] / (this.props.responsive.height - this.graphPaddingTop) - 1;
|
||||||
|
const y =
|
||||||
|
2 *
|
||||||
|
(1 - pin[1] / (this.props.responsive.height - this.graphPaddingTop)) -
|
||||||
|
1;
|
||||||
const pout = [x + inverse[12], y + inverse[13]];
|
const pout = [x + inverse[12], y + inverse[13]];
|
||||||
return [(pout[0] + 1) / 2, (pout[1] + 1) / 2];
|
return [(pout[0] + 1) / 2, (pout[1] + 1) / 2];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,38 +5,39 @@ import * as globals from "../../globals";
|
|||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
*******************************************
|
*******************************************
|
||||||
put svg in DOM
|
put svg & brush in DOM
|
||||||
*******************************************
|
*******************************************
|
||||||
******************************************/
|
******************************************/
|
||||||
|
|
||||||
export const setupGraphElements = (
|
export const setupSVGandBrushElements = (
|
||||||
handleBrushSelectAction,
|
handleBrushSelectAction,
|
||||||
handleBrushDeselectAction
|
handleBrushDeselectAction,
|
||||||
|
responsive,
|
||||||
|
graphPaddingTop
|
||||||
) => {
|
) => {
|
||||||
var svg = d3
|
const side = responsive.height - graphPaddingTop;
|
||||||
|
const svg = d3
|
||||||
.select("#graphAttachPoint")
|
.select("#graphAttachPoint")
|
||||||
.append("svg")
|
.append("svg")
|
||||||
.attr("width", globals.graphWidth)
|
.attr("width", side)
|
||||||
.attr("height", globals.graphHeight)
|
.attr("height", side)
|
||||||
.attr("class", `${styles.graphSVG}`);
|
.attr("class", `${styles.graphSVG}`);
|
||||||
|
|
||||||
setupGraphBrush(svg, handleBrushSelectAction, handleBrushDeselectAction);
|
svg.append("g").call(
|
||||||
|
d3
|
||||||
|
.brush()
|
||||||
|
.extent([
|
||||||
|
[0, 0],
|
||||||
|
[
|
||||||
|
responsive.height - graphPaddingTop,
|
||||||
|
responsive.height - graphPaddingTop
|
||||||
|
]
|
||||||
|
])
|
||||||
|
.on("brush", handleBrushSelectAction)
|
||||||
|
.on("end", handleBrushDeselectAction)
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
svg
|
svg
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupGraphBrush = (
|
|
||||||
svg,
|
|
||||||
handleBrushSelectAction,
|
|
||||||
handleBrushDeselectAction
|
|
||||||
) => {
|
|
||||||
svg.append("g").call(
|
|
||||||
d3
|
|
||||||
.brush()
|
|
||||||
.extent([[0, 0], [globals.graphWidth, globals.graphHeight]])
|
|
||||||
.on("brush", handleBrushSelectAction)
|
|
||||||
.on("end", handleBrushDeselectAction)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user