mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-06 16:38:11 +08:00
more lint (#291)
* disable function-paren-newline warning * fix misc lint * lint * remove noop exponentiation
This commit is contained in:
@@ -32,6 +32,7 @@ module.exports = {
|
|||||||
"no-param-reassign": "off",
|
"no-param-reassign": "off",
|
||||||
"object-curly-newline": ["error", { consistent: true }],
|
"object-curly-newline": ["error", { consistent: true }],
|
||||||
"react/prop-types": [0],
|
"react/prop-types": [0],
|
||||||
"space-before-function-paren": "off"
|
"space-before-function-paren": "off",
|
||||||
|
"function-paren-newline": "off"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
// jshint esversion: 6
|
|
||||||
import _ from "lodash";
|
|
||||||
import { project } from "./util";
|
|
||||||
|
|
||||||
import renderQueue from "../../util/renderQueue";
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
******************************************
|
|
||||||
draw loop
|
|
||||||
******************************************
|
|
||||||
******************************************/
|
|
||||||
|
|
||||||
const drawLinesCanvas = (ctx, dimensions, xscale) => d => {
|
|
||||||
ctx.globalAlpha = 0.1;
|
|
||||||
|
|
||||||
if (d.__selected__) {
|
|
||||||
ctx.strokeStyle = d.__color__;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
const coords = project(d, dimensions, xscale);
|
|
||||||
coords.forEach((p, i) => {
|
|
||||||
// this tricky bit avoids rendering null values as 0
|
|
||||||
if (p === null) {
|
|
||||||
// this bit renders horizontal lines on the previous/next
|
|
||||||
// dimensions, so that sandwiched null values are visible
|
|
||||||
if (i > 0) {
|
|
||||||
const prev = coords[i - 1];
|
|
||||||
if (prev !== null) {
|
|
||||||
ctx.moveTo(prev[0], prev[1]);
|
|
||||||
ctx.lineTo(prev[0] + 6, prev[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i < coords.length - 1) {
|
|
||||||
const next = coords[i + 1];
|
|
||||||
if (next !== null) {
|
|
||||||
ctx.moveTo(next[0] - 6, next[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i === 0) {
|
|
||||||
ctx.moveTo(p[0], p[1]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.lineTo(p[0], p[1]);
|
|
||||||
});
|
|
||||||
ctx.stroke();
|
|
||||||
};
|
|
||||||
|
|
||||||
const drawCellLinesUsingRenderQueue = (
|
|
||||||
metadata,
|
|
||||||
dimensions,
|
|
||||||
xscale,
|
|
||||||
ctx,
|
|
||||||
colorAccessor,
|
|
||||||
colorScale
|
|
||||||
) => {
|
|
||||||
const _renderLinesWithQueue = renderQueue(
|
|
||||||
drawLinesCanvas(ctx, dimensions, xscale, colorAccessor, colorScale)
|
|
||||||
).rate(50);
|
|
||||||
_renderLinesWithQueue(metadata);
|
|
||||||
return _renderLinesWithQueue;
|
|
||||||
};
|
|
||||||
|
|
||||||
const drawCellLinesSync = (
|
|
||||||
metadata,
|
|
||||||
dimensions,
|
|
||||||
xscale,
|
|
||||||
ctx,
|
|
||||||
colorAccessor,
|
|
||||||
colorScale
|
|
||||||
) => {
|
|
||||||
const _draw = drawLinesCanvas(
|
|
||||||
ctx,
|
|
||||||
dimensions,
|
|
||||||
xscale,
|
|
||||||
colorAccessor,
|
|
||||||
colorScale
|
|
||||||
);
|
|
||||||
_.each(metadata, _draw);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default drawCellLinesUsingRenderQueue;
|
|
||||||
// export default drawCellLinesUsingRenderQueue;
|
|
||||||
@@ -14,7 +14,7 @@ import setupSVGandBrushElements from "./setupSVGandBrush";
|
|||||||
import actions from "../../actions";
|
import actions from "../../actions";
|
||||||
import _camera from "../../util/camera";
|
import _camera from "../../util/camera";
|
||||||
import _drawPoints from "./drawPointsRegl";
|
import _drawPoints from "./drawPointsRegl";
|
||||||
import { scaleLinear } from "../../util/scaleLinear";
|
import scaleLinear from "../../util/scaleLinear";
|
||||||
|
|
||||||
/* https://bl.ocks.org/mbostock/9078690 - quadtree for onClick / hover selections */
|
/* https://bl.ocks.org/mbostock/9078690 - quadtree for onClick / hover selections */
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import setupScatterplot from "./setupScatterplot";
|
|||||||
import styles from "./scatterplot.css";
|
import styles from "./scatterplot.css";
|
||||||
|
|
||||||
import _drawPoints from "./drawPointsRegl";
|
import _drawPoints from "./drawPointsRegl";
|
||||||
import { scaleLinear } from "../../util/scaleLinear";
|
import scaleLinear from "../../util/scaleLinear";
|
||||||
|
|
||||||
import { margin, width, height } from "./util";
|
import { margin, width, height } from "./util";
|
||||||
import { kvCache } from "../../util/stateManager";
|
import { kvCache } from "../../util/stateManager";
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const tiniestFontSize = 12;
|
|||||||
|
|
||||||
export const bolder = 700;
|
export const bolder = 700;
|
||||||
|
|
||||||
export let API = {
|
let _API = {
|
||||||
// prefix: "http://api.clustering.czi.technology/api/",
|
// prefix: "http://api.clustering.czi.technology/api/",
|
||||||
// prefix: "http://tabulamuris.cxg.czi.technology/api/",
|
// prefix: "http://tabulamuris.cxg.czi.technology/api/",
|
||||||
// prefix: "http://api-staging.clustering.czi.technology/api/",
|
// prefix: "http://api-staging.clustering.czi.technology/api/",
|
||||||
@@ -55,15 +55,14 @@ export let API = {
|
|||||||
version: "v0.2/"
|
version: "v0.2/"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (window.CELLXGENE && window.CELLXGENE.API) API = window.CELLXGENE.API;
|
if (window.CELLXGENE && window.CELLXGENE.API) _API = window.CELLXGENE.API;
|
||||||
|
export const API = _API;
|
||||||
|
|
||||||
export const accentFont = "Georgia,Times,Times New Roman,serif";
|
export const accentFont = "Georgia,Times,Times New Roman,serif";
|
||||||
export const maxParagraphWidth = 600;
|
export const maxParagraphWidth = 600;
|
||||||
export const maxControlsWidth = 800;
|
export const maxControlsWidth = 800;
|
||||||
|
|
||||||
export const graphMargin = { top: 20, right: 10, bottom: 30, left: 40 };
|
export const graphMargin = { top: 20, right: 10, bottom: 30, left: 40 };
|
||||||
// export const graphWidth = 1440 /* window width */ - 410 /* sidebar */ - (15 + 15) /* left right padding */ /* but responsive */;
|
|
||||||
// export const graphHeight = 500;
|
|
||||||
export const graphWidth = 700;
|
export const graphWidth = 700;
|
||||||
export const graphHeight = 700;
|
export const graphHeight = 700;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import _ from "lodash";
|
|||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import { interpolateViridis } from "d3-scale-chromatic";
|
import { interpolateViridis } from "d3-scale-chromatic";
|
||||||
import * as globals from "../globals";
|
import * as globals from "../globals";
|
||||||
import { parseRGB } from "../util/parseRGB";
|
import parseRGB from "../util/parseRGB";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
https://medium.com/@jacobp100/you-arent-using-redux-middleware-enough-94ffe991e6
|
https://medium.com/@jacobp100/you-arent-using-redux-middleware-enough-94ffe991e6
|
||||||
|
|||||||
Vendored
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { World, kvCache } from "../util/stateManager";
|
import { World, kvCache } from "../util/stateManager";
|
||||||
import { parseRGB } from "../util/parseRGB";
|
import parseRGB from "../util/parseRGB";
|
||||||
import Crossfilter from "../util/typedCrossfilter";
|
import Crossfilter from "../util/typedCrossfilter";
|
||||||
import * as globals from "../globals";
|
import * as globals from "../globals";
|
||||||
|
|
||||||
|
|||||||
+16
-23
@@ -1,9 +1,9 @@
|
|||||||
// jshint esversion: 6
|
// jshint esversion: 6
|
||||||
var createCamera = require("orbit-camera");
|
const createCamera = require("orbit-camera");
|
||||||
var createScroll = require("scroll-speed");
|
const createScroll = require("scroll-speed");
|
||||||
var mp = require("mouse-position");
|
const mp = require("mouse-position");
|
||||||
var mb = require("mouse-pressed");
|
const mb = require("mouse-pressed");
|
||||||
var key = require("key-pressed");
|
const key = require("key-pressed");
|
||||||
|
|
||||||
const panSpeed = 0.4;
|
const panSpeed = 0.4;
|
||||||
const scaleSpeed = 0.5;
|
const scaleSpeed = 0.5;
|
||||||
@@ -17,20 +17,19 @@ function attachCamera(canvas, opts) {
|
|||||||
opts.scale = opts.scale !== false;
|
opts.scale = opts.scale !== false;
|
||||||
opts.rotate = opts.rotate !== false;
|
opts.rotate = opts.rotate !== false;
|
||||||
|
|
||||||
var scroll = createScroll(canvas, opts.scale);
|
const scroll = createScroll(canvas, opts.scale);
|
||||||
var mbut = mb(canvas, opts.rotate);
|
const mbut = mb(canvas, opts.rotate);
|
||||||
var mpos = mp(canvas);
|
const mpos = mp(canvas);
|
||||||
var camera = createCamera([0, 0, 1], [0, 0, -1], [0, 1, 0]);
|
const camera = createCamera([0, 0, 1], [0, 0, -1], [0, 1, 0]);
|
||||||
|
|
||||||
camera.tick = tick;
|
camera.tick = tick;
|
||||||
|
|
||||||
return camera;
|
return camera;
|
||||||
|
|
||||||
function tick() {
|
function tick() {
|
||||||
var ctrl = key("<control>") || key("<alt>");
|
const ctrl = key("<control>") || key("<alt>");
|
||||||
var alt = key("<shift>");
|
const alt = key("<shift>");
|
||||||
var height = canvas.height;
|
const { height, width } = canvas;
|
||||||
var width = canvas.width;
|
|
||||||
|
|
||||||
if (opts.rotate && mbut.left && ctrl && !alt) {
|
if (opts.rotate && mbut.left && ctrl && !alt) {
|
||||||
camera.rotate(
|
camera.rotate(
|
||||||
@@ -41,23 +40,17 @@ function attachCamera(canvas, opts) {
|
|||||||
|
|
||||||
if ((opts.pan && mbut.right) || (mbut.left && !ctrl && !alt)) {
|
if ((opts.pan && mbut.right) || (mbut.left && !ctrl && !alt)) {
|
||||||
camera.pan([
|
camera.pan([
|
||||||
panSpeed *
|
((panSpeed * (mpos[0] - mpos.prev[0])) / width) * camera.distance,
|
||||||
(mpos[0] - mpos.prev[0]) /
|
((panSpeed * (mpos[1] - mpos.prev[1])) / height) * camera.distance
|
||||||
width *
|
|
||||||
Math.pow(camera.distance, 1),
|
|
||||||
panSpeed *
|
|
||||||
(mpos[1] - mpos.prev[1]) /
|
|
||||||
height *
|
|
||||||
Math.pow(camera.distance, 1)
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.scale && scroll[1]) {
|
if (opts.scale && scroll[1]) {
|
||||||
camera.distance *= Math.exp(scroll[1] * scaleSpeed / height);
|
camera.distance *= Math.exp((scroll[1] * scaleSpeed) / height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.scale && (mbut.middle || (mbut.left && !ctrl && alt))) {
|
if (opts.scale && (mbut.middle || (mbut.left && !ctrl && alt))) {
|
||||||
var d = mpos.y - mpos.prevY;
|
const d = mpos.y - mpos.prevY;
|
||||||
if (!d) return;
|
if (!d) return;
|
||||||
|
|
||||||
camera.distance *= Math.exp(d / height);
|
camera.distance *= Math.exp(d / height);
|
||||||
|
|||||||
+10
-11
@@ -1,28 +1,27 @@
|
|||||||
// jshint esversion: 6
|
// jshint esversion: 6
|
||||||
import { scaleRGB } from "./scaleRGB";
|
import scaleRGB from "./scaleRGB";
|
||||||
|
|
||||||
// maintain a cache of already parsed RGB names, as it is reasonably expensive
|
// maintain a cache of already parsed RGB names, as it is reasonably expensive
|
||||||
// to do this operation. This lets us have speed, but keep the pleasant ability
|
// to do this operation. This lets us have speed, but keep the pleasant ability
|
||||||
// to talk about colors by their text description eg, 'rgb(0,0,1)'
|
// to talk about colors by their text description eg, 'rgb(0,0,1)'
|
||||||
//
|
//
|
||||||
const colorCache = new Object(null); // no prototype
|
const colorCache = {};
|
||||||
|
|
||||||
function parseColorName(c) {
|
function parseColorName(c) {
|
||||||
if (c[0] !== "#") {
|
if (c[0] !== "#") {
|
||||||
const _c = c.replace(/[^\d,.]/g, "").split(",");
|
const _c = c.replace(/[^\d,.]/g, "").split(",");
|
||||||
return [scaleRGB(+_c[0]), scaleRGB(+_c[1]), scaleRGB(+_c[2])];
|
return [scaleRGB(+_c[0]), scaleRGB(+_c[1]), scaleRGB(+_c[2])];
|
||||||
} else {
|
|
||||||
var parsedHex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(c);
|
|
||||||
return [
|
|
||||||
scaleRGB(parseInt(parsedHex[1], 16)),
|
|
||||||
scaleRGB(parseInt(parsedHex[2], 16)),
|
|
||||||
scaleRGB(parseInt(parsedHex[3], 16))
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
const parsedHex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(c);
|
||||||
|
return [
|
||||||
|
scaleRGB(parseInt(parsedHex[1], 16)),
|
||||||
|
scaleRGB(parseInt(parsedHex[2], 16)),
|
||||||
|
scaleRGB(parseInt(parsedHex[3], 16))
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const parseRGB = c => {
|
export default c => {
|
||||||
var cv = colorCache[c];
|
let cv = colorCache[c];
|
||||||
if (!cv) {
|
if (!cv) {
|
||||||
cv = parseColorName(c);
|
cv = parseColorName(c);
|
||||||
colorCache[c] = cv;
|
colorCache[c] = cv;
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
// jshint esversion: 6
|
|
||||||
/*****************************************
|
|
||||||
******************************************
|
|
||||||
Render Queue via http://bl.ocks.org/syntagmatic/raw/3341641/render-queue.js
|
|
||||||
******************************************
|
|
||||||
******************************************/
|
|
||||||
|
|
||||||
const renderQueue = function(callback1234) {
|
|
||||||
var _queue = [], // data to be rendered
|
|
||||||
_rate = 300, // number of calls per frame
|
|
||||||
_invalidate = function() {}, // invalidate last render queue
|
|
||||||
_clear = function() {}; // clearing function
|
|
||||||
|
|
||||||
var rq = function(ARRAY_FROM_CELLXGENE) {
|
|
||||||
if (ARRAY_FROM_CELLXGENE) rq.data(ARRAY_FROM_CELLXGENE);
|
|
||||||
_invalidate();
|
|
||||||
_clear();
|
|
||||||
rq.render();
|
|
||||||
};
|
|
||||||
|
|
||||||
rq.render = function() {
|
|
||||||
var valid = true;
|
|
||||||
_invalidate = rq.invalidate = function() {
|
|
||||||
valid = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
function doFrame() {
|
|
||||||
if (!valid) return true;
|
|
||||||
var chunk = _queue.splice(0, _rate);
|
|
||||||
chunk.map(callback1234);
|
|
||||||
timer_frame(doFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
doFrame();
|
|
||||||
};
|
|
||||||
|
|
||||||
rq.data = function(ARRAY_FROM_CELLXGENE) {
|
|
||||||
_invalidate();
|
|
||||||
_queue = ARRAY_FROM_CELLXGENE.slice(0); // creates a copy of the data
|
|
||||||
return rq;
|
|
||||||
};
|
|
||||||
|
|
||||||
rq.add = function(data) {
|
|
||||||
_queue = _queue.concat(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
rq.rate = function(value) {
|
|
||||||
if (!arguments.length) return _rate;
|
|
||||||
_rate = value;
|
|
||||||
return rq;
|
|
||||||
};
|
|
||||||
|
|
||||||
rq.remaining = function() {
|
|
||||||
return _queue.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// clear the canvas
|
|
||||||
rq.clear = function(func) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
_clear();
|
|
||||||
return rq;
|
|
||||||
}
|
|
||||||
_clear = func;
|
|
||||||
return rq;
|
|
||||||
};
|
|
||||||
|
|
||||||
rq.invalidate = _invalidate;
|
|
||||||
|
|
||||||
var timer_frame =
|
|
||||||
window.requestAnimationFrame ||
|
|
||||||
window.webkitRequestAnimationFrame ||
|
|
||||||
window.mozRequestAnimationFrame ||
|
|
||||||
window.oRequestAnimationFrame ||
|
|
||||||
window.msRequestAnimationFrame ||
|
|
||||||
function(callback) {
|
|
||||||
setTimeout(callback, 17);
|
|
||||||
};
|
|
||||||
|
|
||||||
return rq;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default renderQueue;
|
|
||||||
@@ -8,11 +8,9 @@
|
|||||||
// myScale(0) === -1
|
// myScale(0) === -1
|
||||||
// this is is equivalent to d3.scaleLinear().domain([0,1]).range([-1,1])
|
// this is is equivalent to d3.scaleLinear().domain([0,1]).range([-1,1])
|
||||||
|
|
||||||
export const scaleLinear = (domain, range) => {
|
export default (domain, range) => {
|
||||||
const domainStart = domain[0];
|
const domainStart = domain[0];
|
||||||
const scale = (range[1] - range[0]) / (domain[1] - domain[0]);
|
const scale = (range[1] - range[0]) / (domain[1] - domain[0]);
|
||||||
const rangeStart = range[0];
|
const rangeStart = range[0];
|
||||||
return function(value) {
|
return value => (value - domainStart) * scale + rangeStart;
|
||||||
return (value - domainStart) * scale + rangeStart;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// jshint esversion: 6
|
// jshint esversion: 6
|
||||||
export const scaleRGB = input => {
|
export default input => {
|
||||||
const outputMax = 1;
|
const outputMax = 1;
|
||||||
const outputMin = 0;
|
const outputMin = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
// jshint esversion: 6
|
|
||||||
|
|
||||||
// In the case where the REST server does not implement data schema
|
|
||||||
// declaration, we attempt to deduce it by sniffing the data.
|
|
||||||
//
|
|
||||||
export function createSchemaByDataSniffing(ranges) {
|
|
||||||
let schema = {};
|
|
||||||
_.forEach(ranges, (value, key) => {
|
|
||||||
schema[key] = {
|
|
||||||
displayname: key,
|
|
||||||
variabletype: value.options ? "categorical" : "continuous"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Metadata field type is inferred by sniffing the data. This has some risks.
|
|
||||||
// Caveats:
|
|
||||||
// * Values have been converted to native JS objects by the JSON parser.
|
|
||||||
// * Lots of assumptions about he REST API behaving properly (eg, min/max
|
|
||||||
// are the same type, etc).
|
|
||||||
let type;
|
|
||||||
if (schema[key].variabletype === "continuous" && value.range) {
|
|
||||||
// Use min/max as a proxy for all data.
|
|
||||||
const min = value.range.min;
|
|
||||||
const max = value.range.max;
|
|
||||||
type =
|
|
||||||
typeof min !== "number" || typeof max !== "number"
|
|
||||||
? "string"
|
|
||||||
: Number.isSafeInteger(min) && Number.isSafeInteger(max)
|
|
||||||
? "int"
|
|
||||||
: "float";
|
|
||||||
} else {
|
|
||||||
// use an option value as a proxy for all data
|
|
||||||
const aVal = value.options[0];
|
|
||||||
type =
|
|
||||||
typeof aVal !== "number"
|
|
||||||
? "string"
|
|
||||||
: Number.isSafeInteger(aVal) ? "int" : "float";
|
|
||||||
}
|
|
||||||
schema[key].type = type;
|
|
||||||
});
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
@@ -83,7 +83,7 @@ class PositiveIntervals {
|
|||||||
|
|
||||||
if (i === points.length - 1 || p[0] !== points[i + 1][0]) {
|
if (i === points.length - 1 || p[0] !== points[i + 1][0]) {
|
||||||
if (aDepth === 1 && depth === 1) {
|
if (aDepth === 1 && depth === 1) {
|
||||||
intervalStart = p[0];
|
[intervalStart] = p;
|
||||||
} else if (intervalStart !== undefined) {
|
} else if (intervalStart !== undefined) {
|
||||||
res.push([intervalStart, p[0]]);
|
res.push([intervalStart, p[0]]);
|
||||||
intervalStart = undefined;
|
intervalStart = undefined;
|
||||||
@@ -113,7 +113,7 @@ class PositiveIntervals {
|
|||||||
const p = points[i];
|
const p = points[i];
|
||||||
depth += p[2] ? 1 : -1;
|
depth += p[2] ? 1 : -1;
|
||||||
if (depth === 2) {
|
if (depth === 2) {
|
||||||
intervalStart = p[0];
|
[intervalStart] = p;
|
||||||
} else if (intervalStart !== undefined) {
|
} else if (intervalStart !== undefined) {
|
||||||
res.push([intervalStart, p[0]]);
|
res.push([intervalStart, p[0]]);
|
||||||
intervalStart = undefined;
|
intervalStart = undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user