diff --git a/src/components/graph/drawGraphRegl.js b/src/components/graph/drawGraphRegl.js new file mode 100644 index 00000000..d9e3389e --- /dev/null +++ b/src/components/graph/drawGraphRegl.js @@ -0,0 +1,78 @@ +import mat4 from 'gl-mat4'; +import fit from 'canvas-fit'; +import _camera from '../../util/camera.js' +import _regl from 'regl' +import _drawPoints from './drawPointsRegl' + +// setup canvas and camera +const canvas = document.body.appendChild(document.createElement('canvas')) +console.log('canvas',canvas) +// css(canvas, {zIndex: -1000}) + +const camera = _camera(canvas, {scale: true, rotate: false}); +const regl = _regl(canvas) + +window.addEventListener('resize', fit(canvas), false) + +// add explanation +const div = document.createElement('h1') +// div.innerHTML = 'press spacebar to change' +// css(div, {'font-family': 'monospace', 'text-align': 'center'}) +// document.body.appendChild(div) + +// import draw functions +const drawPoints = _drawPoints(regl) + +// 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 = 3e4 + +// preallocate buffers +const pointBuffer = regl.buffer(count)(generatePoints(count)) +const colorBuffer = regl.buffer(count)(generateColors(count)) + +// update on spacebar +document.body.onkeyup = function(e){ + if (e.keyCode == 32){ + pointBuffer(generatePoints(count)) + colorBuffer(generateColors(count)) + } +} + +regl.frame(({viewportWidth, viewportHeight, time}) => { + + 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() +}) diff --git a/src/components/graph/drawPointsRegl.js b/src/components/graph/drawPointsRegl.js new file mode 100644 index 00000000..87df4c49 --- /dev/null +++ b/src/components/graph/drawPointsRegl.js @@ -0,0 +1,47 @@ +const mat4 = require('gl-mat4') + +export default function (regl) { + return regl({ + vert: ` + precision mediump float; + attribute vec2 position; + attribute vec3 color; + uniform float distance; + uniform mat4 projection, view; + varying vec3 fragColor; + void main() { + gl_PointSize = 30.0 / pow(distance, 2.5); + gl_Position = projection * view * vec4(position.x, -position.y, 0, 1); + fragColor = color; + }`, + + frag: ` + precision mediump float; + varying vec3 fragColor; + void main() { + if (length(gl_PointCoord.xy - 0.5) > 0.5) { + discard; + } + gl_FragColor = vec4(fragColor, 1); + }`, + + attributes: { + position: regl.prop('position'), + color: regl.prop('color') + }, + + uniforms: { + distance: regl.prop('distance'), + view: regl.prop('view'), + projection: (context, props) => + mat4.perspective([], + Math.PI / 2, + context.viewportWidth * props.scale / context.viewportHeight, + 0.01, 1000), + }, + + count: regl.prop('count'), + + primitive: 'points' + }) +} diff --git a/src/components/graph/graph.js b/src/components/graph/graph.js index 91b34ff6..c79811d3 100644 --- a/src/components/graph/graph.js +++ b/src/components/graph/graph.js @@ -6,6 +6,7 @@ import {setupGraphElements, drawGraphUsingRenderQueue} from "./drawGraph"; import SectionHeader from "../framework/sectionHeader"; import { connect } from "react-redux"; import actions from "../../actions"; +import drawScatterplotRegl from "./drawGraphRegl"; @connect((state) => { @@ -37,6 +38,36 @@ class Graph extends React.Component { brush: null, }; } + componentDidMount() { + // const {svg, ctx} = setupGraphElements( + // this.handleBrushSelectAction.bind(this), + // this.handleBrushDeselectAction.bind(this) + // ); + // this.setState({svg, ctx}); + console.log('div', this.graphAttachPointDiv) + } + componentWillReceiveProps(nextProps) { + /* 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, + ) + } + } handleBrushSelectAction() { /* No idea why d3 event scope works like this @@ -74,38 +105,6 @@ class Graph extends React.Component { }) } } - componentWillReceiveProps(nextProps) { - /* 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, - ) - } - } - - componentDidMount() { - const {svg, ctx} = setupGraphElements( - this.handleBrushSelectAction.bind(this), - this.handleBrushDeselectAction.bind(this) - ); - this.setState({svg, ctx}); - } - handleOpacityRangeChange(e) { this.props.dispatch({ type: "change opacity deselected cells in 2d graph background", @@ -150,7 +149,10 @@ class Graph extends React.Component { step="0.01" /> -