mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-08 06:08:12 +08:00
subsetting graph with continuous
This commit is contained in:
@@ -29,9 +29,16 @@ import {
|
|||||||
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 metadata = state.cells.cells && state.cells.cells.data.metadata ? state.cells.cells.data.metadata : null;
|
const metadata = state.cells.cells && state.cells.cells.data.metadata ? state.cells.cells.data.metadata : null;
|
||||||
|
|
||||||
|
const initializeRanges = state.initialize.data && state.initialize.data.data.ranges ? state.initialize.data.data.ranges : null;
|
||||||
|
const initializeMetadata = state.initialize.data && state.initialize.data.data.metadata ? state.initialize.data.data.metadata : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ranges,
|
ranges,
|
||||||
metadata,
|
metadata,
|
||||||
|
initializeRanges,
|
||||||
|
initializeMetadata,
|
||||||
|
color: state.controls.color,
|
||||||
|
continuousSelection: state.controls.continuousSelection
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
class Continuous extends React.Component {
|
class Continuous extends React.Component {
|
||||||
@@ -41,7 +48,6 @@ class Continuous extends React.Component {
|
|||||||
svg: null,
|
svg: null,
|
||||||
ctx: null,
|
ctx: null,
|
||||||
axes: null,
|
axes: null,
|
||||||
parallelExists: false,
|
|
||||||
dimensions: null,
|
dimensions: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -56,12 +62,16 @@ class Continuous extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
this.maybeDrawLines(nextProps);
|
||||||
|
this.maybeDrawAxes(nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeDrawAxes(nextProps) {
|
||||||
if (
|
if (
|
||||||
nextProps.ranges &&
|
!this.state.axes &&
|
||||||
!this.state.parallelExists
|
nextProps.initializeRanges /* we assume if this is present, everything else is too */
|
||||||
) {
|
) {
|
||||||
const dimensions = createDimensions(nextProps.ranges);
|
const dimensions = createDimensions(nextProps.initializeRanges);
|
||||||
const xscale = d3.scalePoint()
|
const xscale = d3.scalePoint()
|
||||||
.domain(d3.range(dimensions.length))
|
.domain(d3.range(dimensions.length))
|
||||||
.range([0, width]);
|
.range([0, width]);
|
||||||
@@ -70,16 +80,10 @@ class Continuous extends React.Component {
|
|||||||
processedMetadata,
|
processedMetadata,
|
||||||
processedDimensions
|
processedDimensions
|
||||||
} = processData(
|
} = processData(
|
||||||
nextProps.metadata,
|
nextProps.initializeMetadata,
|
||||||
dimensions
|
dimensions
|
||||||
)
|
)
|
||||||
|
|
||||||
const _drawCellLines = this.drawCellLines(
|
|
||||||
processedMetadata,
|
|
||||||
processedDimensions,
|
|
||||||
xscale
|
|
||||||
);
|
|
||||||
|
|
||||||
const axes = drawAxes(
|
const axes = drawAxes(
|
||||||
this.state.svg,
|
this.state.svg,
|
||||||
this.state.ctx,
|
this.state.ctx,
|
||||||
@@ -88,20 +92,62 @@ class Continuous extends React.Component {
|
|||||||
xscale,
|
xscale,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
_drawCellLines,
|
this.handleBrushAction.bind(this),
|
||||||
)
|
);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
parallelExists: true,
|
|
||||||
dimensions,
|
|
||||||
axes,
|
axes,
|
||||||
|
xscale,
|
||||||
|
processedMetadata,
|
||||||
|
processedDimensions,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeDrawLines(nextProps) {
|
||||||
|
if (
|
||||||
|
nextProps.ranges &&
|
||||||
|
this.state.axes /* this may cause things to never render :/ forceUpdate? */
|
||||||
|
) {
|
||||||
|
if (this.state._drawCellLines) {
|
||||||
|
|
||||||
|
this.state._drawCellLines.invalidate();
|
||||||
|
}
|
||||||
|
const dimensions = createDimensions(nextProps.ranges);
|
||||||
|
|
||||||
|
const {
|
||||||
|
processedMetadata,
|
||||||
|
processedDimensions
|
||||||
|
} = processData(
|
||||||
|
nextProps.metadata,
|
||||||
|
dimensions
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log('draw cell lines', processedMetadata, processedDimensions)
|
||||||
|
const _drawCellLines = this.drawCellLines(
|
||||||
|
_.filter(processedMetadata, (d) => { return nextProps.continuousSelection.indexOf(d.CellName) > -1 }),
|
||||||
|
processedDimensions,
|
||||||
|
this.state.xscale
|
||||||
|
);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
dimensions,
|
||||||
|
_drawCellLines,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleBrushAction (selection) {
|
||||||
|
this.props.dispatch({
|
||||||
|
type: "continuous selection using parallel coords brushing",
|
||||||
|
data: _.map(selection, (d) => { return d.CellName })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
drawCellLines (metadata, dimensions, xscale) {
|
drawCellLines (metadata, dimensions, xscale) {
|
||||||
const _drawCellLines = renderQueue(
|
const _drawCellLines = renderQueue(
|
||||||
drawLinesCanvas(this.state.ctx, dimensions, xscale)
|
drawLinesCanvas(this.state.ctx, dimensions, this.state.xscale)
|
||||||
).rate(50);
|
).rate(50);
|
||||||
|
|
||||||
this.state.ctx.clearRect(0,0,width,height);
|
this.state.ctx.clearRect(0,0,width,height);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const drawAxes = (
|
|||||||
xscale,
|
xscale,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
render
|
handleBrushAction,
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
/*****************************************
|
/*****************************************
|
||||||
@@ -23,7 +23,7 @@ const drawAxes = (
|
|||||||
******************************************/
|
******************************************/
|
||||||
|
|
||||||
function brush () {
|
function brush () {
|
||||||
render.invalidate();
|
// _drawCellLines.invalidate(); /* this should be moved up */
|
||||||
|
|
||||||
var actives = [];
|
var actives = [];
|
||||||
svg.selectAll(".parcoords_axis .parcoords_brush")
|
svg.selectAll(".parcoords_axis .parcoords_brush")
|
||||||
@@ -48,15 +48,15 @@ const drawAxes = (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Reset canvas */
|
|
||||||
ctx.clearRect(0, 0, width, height);
|
|
||||||
ctx.globalAlpha = d3.min([0.85 / Math.pow(selected.length, 0.3), 1]);
|
|
||||||
|
|
||||||
/* send the selected cells to redux */
|
/* send the selected cells to redux */
|
||||||
|
handleBrushAction(selected)
|
||||||
|
|
||||||
|
/* Reset canvas */
|
||||||
|
// ctx.clearRect(0, 0, width, height);
|
||||||
|
// ctx.globalAlpha = d3.min([0.85 / Math.pow(selected.length, 0.3), 1]);
|
||||||
|
|
||||||
/* pass the result of the filter above to a fresh canvas, using RAF */
|
/* pass the result of the filter above to a fresh canvas, using RAF */
|
||||||
render(selected);
|
// _drawCellLines(selected);
|
||||||
|
|
||||||
/* text beneath */
|
/* text beneath */
|
||||||
// output.text(d3.tsvFormat(selected.slice(0,22)));
|
// output.text(d3.tsvFormat(selected.slice(0,22)));
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export const project = (d, dimensions, xscale) => {
|
|||||||
|
|
||||||
export const processData = (metadata, dimensions) => {
|
export const processData = (metadata, dimensions) => {
|
||||||
// shuffle the metadata! - or not, this is a visual effect
|
// shuffle the metadata! - or not, this is a visual effect
|
||||||
metadata = d3.shuffle(metadata);
|
// metadata = d3.shuffle(metadata);
|
||||||
|
|
||||||
metadata.forEach((d) => {
|
metadata.forEach((d) => {
|
||||||
dimensions.forEach((p) => {
|
dimensions.forEach((p) => {
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ export const drawGraph = (
|
|||||||
expressionsCountsMap,
|
expressionsCountsMap,
|
||||||
color,
|
color,
|
||||||
ranges,
|
ranges,
|
||||||
metadata
|
metadata,
|
||||||
|
continuousSelection,
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
/* clear canvas */
|
/* clear canvas */
|
||||||
@@ -82,8 +83,12 @@ export const drawGraph = (
|
|||||||
// .domain([0, expressionsCountsMap.maxValue])
|
// .domain([0, expressionsCountsMap.maxValue])
|
||||||
// .range([1,0])
|
// .range([1,0])
|
||||||
|
|
||||||
/* shuffle the data to overcome render order hiding cells */
|
if (continuousSelection) {
|
||||||
data = d3.shuffle(data);
|
data = _.filter(data, (d) => {return continuousSelection.indexOf(d[0]) > -1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shuffle the data to overcome render order hiding cells, & filter first */
|
||||||
|
// data = d3.shuffle(data);
|
||||||
|
|
||||||
data.forEach((p, i) => {
|
data.forEach((p, i) => {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
|
|||||||
Reference in New Issue
Block a user