mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-02 14:18:12 +08:00
color by gene expression
This commit is contained in:
@@ -11,8 +11,6 @@ const x = d3.scaleLinear()
|
|||||||
const y = d3.scaleLinear()
|
const y = d3.scaleLinear()
|
||||||
.range([height, 0]);
|
.range([height, 0]);
|
||||||
|
|
||||||
const cellFillColor = "rgba(0,0,0,.5)";
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
*******************************************
|
*******************************************
|
||||||
put svg & canvas in DOM
|
put svg & canvas in DOM
|
||||||
@@ -52,15 +50,20 @@ export const setupGraphElements = (data) => {
|
|||||||
*******************************************
|
*******************************************
|
||||||
******************************************/
|
******************************************/
|
||||||
|
|
||||||
export const drawGraph = (data, context) => {
|
export const drawGraph = (data, context, expressionsCountsMap) => {
|
||||||
|
|
||||||
/* clear canvas */
|
/* clear canvas */
|
||||||
context.clearRect(0, 0, width, height);
|
context.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
|
/* ! create a scale to map between expression values and colors, remove to somewhere else */
|
||||||
|
const expressionToColorScale = d3.scaleLog()
|
||||||
|
.domain([0, expressionsCountsMap.maxValue])
|
||||||
|
.range([1,0])
|
||||||
|
|
||||||
/* shuffle the data to overcome render order hiding cells */
|
/* shuffle the data to overcome render order hiding cells */
|
||||||
data = d3.shuffle(data);
|
data = d3.shuffle(data);
|
||||||
|
|
||||||
/* loop! */
|
/* loop */
|
||||||
data.forEach((p, i) => {
|
data.forEach((p, i) => {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
/* context.arc(x,y,r,sAngle,eAngle,counterclockwise); */
|
/* context.arc(x,y,r,sAngle,eAngle,counterclockwise); */
|
||||||
@@ -72,6 +75,17 @@ export const drawGraph = (data, context) => {
|
|||||||
2 * Math.PI /* eAngle */
|
2 * Math.PI /* eAngle */
|
||||||
);
|
);
|
||||||
context.fill();
|
context.fill();
|
||||||
context.fillStyle = cellFillColor;
|
|
||||||
|
if (i < 20) {
|
||||||
|
console.log(
|
||||||
|
'0 to 1 scale', expressionToColorScale(expressionsCountsMap[p[0]]),
|
||||||
|
'color', d3.interpolateViridis(expressionToColorScale(
|
||||||
|
expressionsCountsMap[p[0]]
|
||||||
|
))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
context.fillStyle = d3.interpolateViridis(expressionToColorScale(
|
||||||
|
expressionsCountsMap[p[0]]
|
||||||
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,15 @@ class Graph extends React.Component {
|
|||||||
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 (
|
if (
|
||||||
nextProps.data &&
|
nextProps.vertices &&
|
||||||
|
nextProps.expressions &&
|
||||||
|
nextProps.expressionsCountsMap &&
|
||||||
this.state.context
|
this.state.context
|
||||||
) {
|
) {
|
||||||
drawGraph(
|
drawGraph(
|
||||||
nextProps.data.data,
|
nextProps.vertices.data,
|
||||||
this.state.context
|
this.state.context,
|
||||||
|
nextProps.expressionsCountsMap
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-14
@@ -14,15 +14,13 @@ class Home extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
showClustersPlaceholderImage: false,
|
expressions: null,
|
||||||
heatmap: null,
|
vertices: null,
|
||||||
graph: null,
|
coloring: null,
|
||||||
|
metadata: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// d3.csv("http://ec2-34-234-75-156.compute-1.amazonaws.com/api/v0.1/metadata", (d) => {
|
|
||||||
// console.log("from ec2",d)
|
|
||||||
// })
|
|
||||||
|
|
||||||
const prefix = "http://ec2-34-234-75-156.compute-1.amazonaws.com/api/";
|
const prefix = "http://ec2-34-234-75-156.compute-1.amazonaws.com/api/";
|
||||||
const version = "v0.1/";
|
const version = "v0.1/";
|
||||||
@@ -39,16 +37,45 @@ class Home extends React.Component {
|
|||||||
})
|
})
|
||||||
// const expressions = fetch(`${prefix}${version}${expression}`)
|
// const expressions = fetch(`${prefix}${version}${expression}`)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((data) => { this.setState({heatmap: data}) })
|
.then((data) => { this.setState({expressions: data}) })
|
||||||
|
|
||||||
|
|
||||||
const graph = fetch(`${prefix}${version}graph`)
|
const graph = fetch(`${prefix}${version}graph`)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((data) => { this.setState({graph: data}) })
|
.then((data) => { this.setState({vertices: data}) })
|
||||||
|
|
||||||
|
const metadata = d3.csv(`${prefix}${version}metadata`, (data) => {
|
||||||
|
this.setState({metadata: data})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createExpressionsCountsMap () {
|
||||||
|
|
||||||
|
const CHANGE_ME_MAGIC_GENE_INDEX = 3;
|
||||||
|
|
||||||
|
const expressionsCountsMap = {};
|
||||||
|
|
||||||
|
/* currently selected gene */
|
||||||
|
expressionsCountsMap.geneName = this.state.expressions.data.genes[3];
|
||||||
|
|
||||||
|
let maxExpressionValue = 0;
|
||||||
|
|
||||||
|
/* create map of expressions for every cell */
|
||||||
|
this.state.expressions.data.cells.map((c) => {
|
||||||
|
/* cellname = 234 */
|
||||||
|
expressionsCountsMap[c.cellname] = c["e"][CHANGE_ME_MAGIC_GENE_INDEX];
|
||||||
|
/* collect the maximum value as we iterate */
|
||||||
|
if (c["e"][CHANGE_ME_MAGIC_GENE_INDEX] > maxExpressionValue) {
|
||||||
|
maxExpressionValue = c["e"][CHANGE_ME_MAGIC_GENE_INDEX]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expressionsCountsMap.maxValue = maxExpressionValue;
|
||||||
|
|
||||||
|
return expressionsCountsMap;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
console.log('heatmap', this.state.heatmap)
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Helmet title="cellxgene" />
|
<Helmet title="cellxgene" />
|
||||||
@@ -59,18 +86,20 @@ class Home extends React.Component {
|
|||||||
Refresh.
|
Refresh.
|
||||||
</button>
|
</button>
|
||||||
<h3 style={{marginTop: 50}}> Gene selection criteria </h3>
|
<h3 style={{marginTop: 50}}> Gene selection criteria </h3>
|
||||||
{false ? <Joy data={this.state.heatmap && this.state.heatmap.data}/> : ""}
|
{false ? <Joy data={this.state.expressions && this.state.expressions.data}/> : ""}
|
||||||
|
|
||||||
<Categorical/>
|
<Categorical/>
|
||||||
<Continuous/>
|
<Continuous/>
|
||||||
<button
|
<button
|
||||||
onClick={() => { this.setState({showClustersPlaceholderImage: true}) }}
|
|
||||||
style={{marginBottom: 20}}
|
style={{marginBottom: 20}}
|
||||||
className={buttonStyles.primaryButton}>
|
className={buttonStyles.primaryButton}>
|
||||||
Compute clustering using [n] cells in current metadata selection
|
Compute clustering using [n] cells in current metadata selection
|
||||||
</button>
|
</button>
|
||||||
<Graph data={this.state.graph}/>
|
<Graph
|
||||||
{this.state.showClustersPlaceholderImage ? <img width={750} src="https://s10.postimg.org/s6z3zbcvt/tsne.png"></img> : null}
|
vertices={this.state.vertices}
|
||||||
|
expressions={this.state.expressions}
|
||||||
|
expressionsCountsMap={this.state.expressions && this.state.expressions ? this.createExpressionsCountsMap() : null}
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user