mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-08 07:18:12 +08:00
rendering color and position
This commit is contained in:
+137
-17
@@ -8,6 +8,35 @@ import { connect } from "react-redux";
|
|||||||
import actions from "../../actions";
|
import actions from "../../actions";
|
||||||
import drawScatterplotRegl from "./drawGraphRegl";
|
import drawScatterplotRegl from "./drawGraphRegl";
|
||||||
|
|
||||||
|
import mat4 from 'gl-mat4';
|
||||||
|
import fit from 'canvas-fit';
|
||||||
|
import _camera from '../../util/camera.js'
|
||||||
|
import _regl from 'regl'
|
||||||
|
import _drawPoints from './drawPointsRegl'
|
||||||
|
|
||||||
|
// import data generators
|
||||||
|
const generatePoints = function (count) {
|
||||||
|
return Array(count).fill().map(function () {
|
||||||
|
return [
|
||||||
|
Math.random() - 0.5,
|
||||||
|
Math.random() - 0.5
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateColors = function (count) {
|
||||||
|
return Array(count).fill().map(function () {
|
||||||
|
return [
|
||||||
|
Math.random(),
|
||||||
|
Math.random(),
|
||||||
|
Math.random()
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// set constants
|
||||||
|
const count = 1993
|
||||||
|
|
||||||
|
|
||||||
@connect((state) => {
|
@connect((state) => {
|
||||||
|
|
||||||
const vertices = state.cells.cells && state.cells.cells.data.graph ? state.cells.cells.data.graph : null;
|
const vertices = state.cells.cells && state.cells.cells.data.graph ? state.cells.cells.data.graph : null;
|
||||||
@@ -44,28 +73,116 @@ class Graph extends React.Component {
|
|||||||
// this.handleBrushDeselectAction.bind(this)
|
// this.handleBrushDeselectAction.bind(this)
|
||||||
// );
|
// );
|
||||||
// this.setState({svg, ctx});
|
// this.setState({svg, ctx});
|
||||||
console.log('div', this.graphAttachPointDiv)
|
|
||||||
|
// setup canvas and camera
|
||||||
|
const camera = _camera(this.reglCanvas, {scale: true, rotate: false});
|
||||||
|
const regl = _regl(this.reglCanvas)
|
||||||
|
|
||||||
|
const drawPoints = _drawPoints(regl)
|
||||||
|
|
||||||
|
// preallocate buffers
|
||||||
|
const pointBuffer = regl.buffer(generatePoints(count))
|
||||||
|
const colorBuffer = regl.buffer(generateColors(count))
|
||||||
|
|
||||||
|
|
||||||
|
regl.frame(({viewportWidth, viewportHeight}) => {
|
||||||
|
|
||||||
|
regl.clear({
|
||||||
|
depth: 1,
|
||||||
|
color: [1, 1, 1, 1]
|
||||||
|
})
|
||||||
|
|
||||||
|
drawPoints({
|
||||||
|
distance: camera.distance,
|
||||||
|
color: colorBuffer,
|
||||||
|
position: pointBuffer,
|
||||||
|
count: count,
|
||||||
|
view: camera.view(),
|
||||||
|
scale: viewportHeight / viewportWidth
|
||||||
|
})
|
||||||
|
|
||||||
|
camera.tick()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
regl,
|
||||||
|
pointBuffer,
|
||||||
|
colorBuffer,
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
/* maybe should do a check here to confirm ref exists and pass it? */
|
/* maybe should do a check here to confirm ref exists and pass it? */
|
||||||
|
// if (
|
||||||
|
// this.state.ctx &&
|
||||||
|
// nextProps.vertices
|
||||||
|
// // nextProps.expressions &&
|
||||||
|
// // nextProps.expressionsCountsMap &&
|
||||||
|
// ) {
|
||||||
|
// drawGraphUsingRenderQueue(
|
||||||
|
// this.state.ctx,
|
||||||
|
// nextProps.expressionsCountsMap,
|
||||||
|
// nextProps.colorAccessor,
|
||||||
|
// nextProps.ranges, /* assumption that this exists if vertices does both are on cells */
|
||||||
|
// nextProps.metadata,
|
||||||
|
// nextProps.currentCellSelection,
|
||||||
|
// nextProps.graphBrushSelection,
|
||||||
|
// nextProps.colorScale,
|
||||||
|
// nextProps.graphMap,
|
||||||
|
// nextProps.opacityForDeselectedCells,
|
||||||
|
// )
|
||||||
|
// }
|
||||||
if (
|
if (
|
||||||
this.state.ctx &&
|
this.state.regl &&
|
||||||
nextProps.vertices
|
nextProps.vertices
|
||||||
// nextProps.expressions &&
|
|
||||||
// nextProps.expressionsCountsMap &&
|
|
||||||
) {
|
) {
|
||||||
drawGraphUsingRenderQueue(
|
|
||||||
this.state.ctx,
|
const _currentCellSelectionMap = _.keyBy(nextProps.currentCellSelection, "CellName"); /* move me to the reducer */
|
||||||
nextProps.expressionsCountsMap,
|
|
||||||
nextProps.colorAccessor,
|
const positions = [];
|
||||||
nextProps.ranges, /* assumption that this exists if vertices does both are on cells */
|
const colors = [];
|
||||||
nextProps.metadata,
|
|
||||||
nextProps.currentCellSelection,
|
_.each(nextProps.currentCellSelection, (cell, i) => {
|
||||||
nextProps.graphBrushSelection,
|
if (nextProps.graphMap[cell["CellName"]]) { /* fails silently, sometimes this is undefined, in which case the graph array should be shorter than the cell array, check in reducer */
|
||||||
nextProps.colorScale,
|
positions.push([
|
||||||
nextProps.graphMap,
|
nextProps.graphMap[cell["CellName"]][0],
|
||||||
nextProps.opacityForDeselectedCells,
|
nextProps.graphMap[cell["CellName"]][1]
|
||||||
)
|
])
|
||||||
|
|
||||||
|
const scaleRGB = (input) => {
|
||||||
|
const outputMax = 1;
|
||||||
|
const outputMin = 0;
|
||||||
|
|
||||||
|
const inputMax = 255;
|
||||||
|
const inputMin = 0;
|
||||||
|
|
||||||
|
const percent = (input - inputMin) / (inputMax - inputMin);
|
||||||
|
return percent * (outputMax - outputMin) + outputMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
let c = cell["__color__"];
|
||||||
|
|
||||||
|
if (c[0] !== "#") {
|
||||||
|
const _c = c.replace(/[^\d,.]/g, '').split(',');
|
||||||
|
colors.push([
|
||||||
|
scaleRGB(+_c[0]),
|
||||||
|
scaleRGB(+_c[1]),
|
||||||
|
scaleRGB(+_c[2])
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
var parsedHex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(c);
|
||||||
|
colors.push([
|
||||||
|
scaleRGB(parseInt(parsedHex[1], 16)),
|
||||||
|
scaleRGB(parseInt(parsedHex[2], 16)),
|
||||||
|
scaleRGB(parseInt(parsedHex[3], 16))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.state.pointBuffer(positions)
|
||||||
|
this.state.colorBuffer(colors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleBrushSelectAction() {
|
handleBrushSelectAction() {
|
||||||
@@ -151,7 +268,10 @@ class Graph extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="graphAttachPoint"
|
id="graphAttachPoint"
|
||||||
ref={(div) => { this.graphAttachPointDiv = div}}>
|
>
|
||||||
|
</div>
|
||||||
|
<div style={{padding: 0, margin: 0}}>
|
||||||
|
<canvas width={1500} height={800} style={{border: "1px solid black"}} ref={(canvas) => { this.reglCanvas = canvas}}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user