Files
cellxgene/src/components/graph/drawGraph.js
T
2017-12-12 21:37:19 -08:00

148 lines
4.0 KiB
JavaScript

import styles from "./graph.css";
import renderQueue from "../continuous/renderQueue";
import _ from "lodash";
import * as globals from "../../globals";
/******************************************
*******************************************
put svg & canvas in DOM
*******************************************
******************************************/
export const setupGraphElements = (
handleBrushSelectAction,
handleBrushDeselectAction
) => {
var canvas = d3.select("#graphAttachPoint")
.append("canvas")
.attr("width", globals.graphWidth)
.attr("height", globals.graphHeight)
.attr("class", `${styles.graphCanvas}`);
var ctx = canvas.node().getContext("2d");
var svg = d3.select("#graphAttachPoint").append("svg")
.attr("width", globals.graphWidth)
.attr("height", globals.graphHeight)
.attr("class", `${styles.graphSVG}`)
// .append("g")
// .attr("transform", "translate(" + margin.left + " " + margin.top + ")");
setupGraphBrush(
svg,
handleBrushSelectAction,
handleBrushDeselectAction
);
return {
svg,
ctx
}
}
/******************************************
*******************************************
draw cells on the canvas
*******************************************
******************************************/
export const drawGraph = (
context,
expressionsCountsMap,
colorAccessor,
ranges,
metadata,
currentCellSelection,
graphBrushSelection,
colorScale,
graphMap, /* tmp remove when structure exists on server */
) => {
/* clear canvas */
context.clearRect(0, 0, globals.graphWidth, globals.graphHeight);
// let colorScale = null; /* it could be 'by expression' and that's a special case */
/* ! create a scale to map between expression values and colors, remove to somewhere else */
// const expressionToColorScale = d3.scaleLinear()
// .domain([0, expressionsCountsMap.maxValue])
// .range([1,0])
const data = [];
_.each(currentCellSelection, (cell, i) => {
if (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 */
data.push([
cell["CellName"],
graphMap[cell["CellName"]][0],
graphMap[cell["CellName"]][1]
])
}
})
/* shuffle the data to overcome render order hiding cells, & filter first */
// data = d3.shuffle(data); /* make me a control */
const _currentCellSelectionMap = _.keyBy(currentCellSelection, "CellName"); /* move me to the reducer */
data.forEach((p, i) => {
context.beginPath();
/* context.arc(x,y,r,sAngle,eAngle,counterclockwise); */
context.arc(
globals.graphXScale(p[1]), /* x */
globals.graphYScale(p[2]), /* y */
2, /* r */
0, /* sAngle */
2 * Math.PI /* eAngle */
);
if (colorAccessor && colorScale) {
context.fillStyle = d3.interpolateViridis(colorScale(
_currentCellSelectionMap[p[0]][colorAccessor]
));
} else {
context.fillStyle = "rgb(0,0,0)";
}
if (_currentCellSelectionMap[p[0]]["__selected__"]) {
context.globalAlpha = 1;
} else {
context.globalAlpha = .2;
}
// if (i < 20) {
// console.log(
// '0 to 1 scale', expressionToColorScale(expressionsCountsMap[p[0]]),
// 'color', d3.interpolateViridis(expressionToColorScale(
// expressionsCountsMap[p[0]]
// ))
// )
// console.log('meta', _.find(metadata, {CellName: p[0]}), color, p)
// }
// context.fillStyle = d3.interpolateViridis(expressionToColorScale(
// expressionsCountsMap[p[0]]
// ));
context.fill();
});
}
const setupGraphBrush = (
svg,
handleBrushSelectAction,
handleBrushDeselectAction
) => {
svg.append("g")
.call(
d3.brush()
.extent([
[0, 0],
[globals.graphWidth, globals.graphHeight]
])
.on("brush", handleBrushSelectAction)
.on("end", handleBrushDeselectAction)
);
}