move colorScale and colorAccessor to redux to make it global

This commit is contained in:
Colin Megill
2017-11-17 14:59:28 -08:00
parent e18f57e6f2
commit 42bef3d6cd
7 changed files with 61 additions and 39 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ class App extends React.Component {
/* /*
first request includes query straight off the url bar for now, first request includes query straight off the url bar for now,
*/ */
this.props.dispatch(actions.requestCells(window.location.search)) this.props.dispatch(actions.requestCells(window.location.search))
+6 -8
View File
@@ -35,8 +35,10 @@ import {
metadata, metadata,
initializeRanges, initializeRanges,
initializeMetadata, initializeMetadata,
color: state.controls.color, colorAccessor: state.controls.colorAccessor,
continuousSelection: state.controls.continuousSelection graphBrushSelection: state.controls.graphBrushSelection,
continuousSelection: state.controls.continuousSelection,
axesHaveBeenDrawn: state.controls.axesHaveBeenDrawn,
} }
}) })
class Continuous extends React.Component { class Continuous extends React.Component {
@@ -49,7 +51,6 @@ class Continuous extends React.Component {
dimensions: null, dimensions: null,
}; };
} }
componentDidMount() { componentDidMount() {
const {svg, ctx} = setupParallelCoordinates( const {svg, ctx} = setupParallelCoordinates(
width, width,
@@ -58,12 +59,10 @@ class Continuous extends React.Component {
); );
this.setState({svg, ctx}) this.setState({svg, ctx})
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
this.maybeDrawLines(nextProps);
this.maybeDrawAxes(nextProps); this.maybeDrawAxes(nextProps);
this.maybeDrawLines(nextProps);
} }
maybeDrawAxes(nextProps) { maybeDrawAxes(nextProps) {
if ( if (
!this.state.axes && !this.state.axes &&
@@ -126,8 +125,7 @@ class Continuous extends React.Component {
this.state.processedDimensions, this.state.processedDimensions,
this.state.xscale, this.state.xscale,
this.state.ctx, this.state.ctx,
width, this.props.colorAccessor,
height
); );
this.setState({ this.setState({
+14 -5
View File
@@ -10,7 +10,12 @@ import renderQueue from "./renderQueue";
****************************************** ******************************************
******************************************/ ******************************************/
const drawLinesCanvas = (ctx, dimensions, xscale) => { const drawLinesCanvas = (
ctx,
dimensions,
xscale,
color,
) => {
return (d) => { return (d) => {
// ctx.strokeStyle = d["Sample.name.color"]; // ctx.strokeStyle = d["Sample.name.color"];
@@ -54,14 +59,18 @@ const drawCellLinesUsingRenderQueue = (
dimensions, dimensions,
xscale, xscale,
ctx, ctx,
width, color,
height
) => { ) => {
const _renderLinesWithQueue = renderQueue( const _renderLinesWithQueue = renderQueue(
drawLinesCanvas(ctx, dimensions, xscale) drawLinesCanvas(
ctx,
dimensions,
xscale,
color
)
).rate(50); ).rate(50);
_renderLinesWithQueue(metadata); _renderLinesWithQueue(metadata);
return _renderLinesWithQueue; return _renderLinesWithQueue;
+8 -6
View File
@@ -22,10 +22,11 @@ const Option = ({name, selected, handleClick}) => {
@connect((state) => { @connect((state) => {
const ranges = state.cells.cells && state.cells.cells.data.ranges ? state.cells.cells.data.ranges : null; const ranges = state.cells.cells && state.cells.cells.data.ranges ? state.cells.cells.data.ranges : null;
const initializeRanges = state.initialize.data && state.initialize.data.data.ranges ? state.initialize.data.data.ranges : null;
return { return {
ranges, ranges,
color: state.controls.color, initializeRanges,
colorAccessor: state.controls.colorAccessor,
} }
}) })
class ColorOptions extends React.Component { class ColorOptions extends React.Component {
@@ -37,17 +38,18 @@ class ColorOptions extends React.Component {
}; };
} }
handleClick (data) { handleClick (name) {
return () => { return () => {
this.props.dispatch({ this.props.dispatch({
type: "color changed", type: "color changed",
data colorAccessor: name,
rangeMaxForColorAccessor: this.props.initializeRanges[name].range.max
}); });
} }
} }
render() { render() {
if (!this.props.ranges) { return null } if (!this.props.ranges || !this.props.initializeRanges) { return null }
return ( return (
<div> <div>
Color: Color:
@@ -61,7 +63,7 @@ class ColorOptions extends React.Component {
return <Option return <Option
key={key} key={key}
handleClick={this.handleClick.bind(this)} handleClick={this.handleClick.bind(this)}
selected={this.props.color === key} selected={this.props.colorAccessor === key}
name={key} name={key}
/> />
} }
+5 -14
View File
@@ -63,27 +63,18 @@ export const drawGraph = (
data, data,
context, context,
expressionsCountsMap, expressionsCountsMap,
color, colorAccessor,
ranges, ranges,
metadata, metadata,
continuousSelection, continuousSelection,
graphBrushSelection, graphBrushSelection,
colorScale,
) => { ) => {
/* clear canvas */ /* clear canvas */
context.clearRect(0, 0, width, height); context.clearRect(0, 0, width, height);
let colorScale = null; /* it could be 'by expression' and that's a special case */ // let colorScale = null; /* it could be 'by expression' and that's a special case */
if (
color &&
ranges[color].range /* set up a continuous scale */
) {
/* this scale should live in redux since it will be consumed by cotinuous as well */
colorScale = d3.scaleLinear()
.domain([0, ranges[color].range.max])
.range([1,0])
}
/* ! create a scale to map between expression values and colors, remove to somewhere else */ /* ! create a scale to map between expression values and colors, remove to somewhere else */
// const expressionToColorScale = d3.scaleLinear() // const expressionToColorScale = d3.scaleLinear()
@@ -133,9 +124,9 @@ export const drawGraph = (
context.globalAlpha = !graphBrushSelection || pointIsInsideBrushBounds ? 1 : .2; context.globalAlpha = !graphBrushSelection || pointIsInsideBrushBounds ? 1 : .2;
if (color) { if (colorAccessor && colorScale) {
context.fillStyle = d3.interpolateViridis(colorScale( context.fillStyle = d3.interpolateViridis(colorScale(
_metadata[p[0]][color] _metadata[p[0]][colorAccessor]
// _.find(metadata, {CellName: p[0]})[color] /* this.state.cells.metadata["23452345325"]["ERCC_reads"] = 20000 would be much faster as key value lookup */ // _.find(metadata, {CellName: p[0]})[color] /* this.state.cells.metadata["23452345325"]["ERCC_reads"] = 20000 would be much faster as key value lookup */
)); ));
} }
+4 -2
View File
@@ -16,7 +16,8 @@ import ColorControl from "../controls/color";
ranges, ranges,
vertices, vertices,
metadata, metadata,
color: state.controls.color, colorAccessor: state.controls.colorAccessor,
colorScale: state.controls.colorScale,
continuousSelection: state.controls.continuousSelection, continuousSelection: state.controls.continuousSelection,
graphBrushSelection: state.controls.graphBrushSelection graphBrushSelection: state.controls.graphBrushSelection
} }
@@ -81,11 +82,12 @@ class Graph extends React.Component {
nextProps.vertices, nextProps.vertices,
this.state.ctx, this.state.ctx,
nextProps.expressionsCountsMap, nextProps.expressionsCountsMap,
nextProps.color, nextProps.colorAccessor,
nextProps.ranges, /* assumption that this exists if vertices does both are on cells */ nextProps.ranges, /* assumption that this exists if vertices does both are on cells */
nextProps.metadata, nextProps.metadata,
nextProps.continuousSelection, /* continuousSelected should probably inform a global 'is active' array rather than be consumed so specifically here */ nextProps.continuousSelection, /* continuousSelected should probably inform a global 'is active' array rather than be consumed so specifically here */
nextProps.graphBrushSelection, nextProps.graphBrushSelection,
nextProps.colorScale,
) )
} }
} }
+23 -3
View File
@@ -1,18 +1,38 @@
const Controls = (state = { const Controls = (state = {
color: null, colorAccessor: null,
colorScale: null,
continuousSelection: null, continuousSelection: null,
graphBrushSelection: null graphBrushSelection: null,
axesHaveBeenDrawn: false,
}, action) => { }, action) => {
switch (action.type) { switch (action.type) {
case "color changed": case "color changed":
return Object.assign({}, state, { return Object.assign({}, state, {
color: action.data, colorAccessor: action.colorAccessor,
colorScale: d3.scaleLinear()
.domain([0, action.rangeMaxForColorAccessor])
.range([1,0])
}); });
case "continuous selection using parallel coords brushing": { case "continuous selection using parallel coords brushing": {
return Object.assign({}, state, { return Object.assign({}, state, {
continuousSelection: action.data, continuousSelection: action.data,
}); });
} }
/* on load, set the selection to 'all', if reactive is true */
case "initialize success":
let allCellNames = null;
if (action.data.data.reactive) { /* we have metadata, get all cell names */
allCellNames = action.data.data.metadata.map((cell) => {
return cell.CellName
})
}
return Object.assign({}, state, {
continuousSelection: allCellNames
});
case "parallel coordinates axes have been drawn":
return Object.assign({}, state, {
axesHaveBeenDrawn: true
});
case "graph brush selection change": case "graph brush selection change":
return Object.assign({}, state, { return Object.assign({}, state, {
graphBrushSelection: action.brushCoords graphBrushSelection: action.brushCoords