mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-27 18:48:11 +08:00
more lint (#291)
* disable function-paren-newline warning * fix misc lint * lint * remove noop exponentiation
This commit is contained in:
@@ -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 _camera from "../../util/camera";
|
||||
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 */
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import setupScatterplot from "./setupScatterplot";
|
||||
import styles from "./scatterplot.css";
|
||||
|
||||
import _drawPoints from "./drawPointsRegl";
|
||||
import { scaleLinear } from "../../util/scaleLinear";
|
||||
import scaleLinear from "../../util/scaleLinear";
|
||||
|
||||
import { margin, width, height } from "./util";
|
||||
import { kvCache } from "../../util/stateManager";
|
||||
|
||||
@@ -47,7 +47,7 @@ export const tiniestFontSize = 12;
|
||||
|
||||
export const bolder = 700;
|
||||
|
||||
export let API = {
|
||||
let _API = {
|
||||
// prefix: "http://api.clustering.czi.technology/api/",
|
||||
// prefix: "http://tabulamuris.cxg.czi.technology/api/",
|
||||
// prefix: "http://api-staging.clustering.czi.technology/api/",
|
||||
@@ -55,15 +55,14 @@ export let API = {
|
||||
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 maxParagraphWidth = 600;
|
||||
export const maxControlsWidth = 800;
|
||||
|
||||
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 graphHeight = 700;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import _ from "lodash";
|
||||
import * as d3 from "d3";
|
||||
import { interpolateViridis } from "d3-scale-chromatic";
|
||||
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
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
import _ from "lodash";
|
||||
import { World, kvCache } from "../util/stateManager";
|
||||
import { parseRGB } from "../util/parseRGB";
|
||||
import parseRGB from "../util/parseRGB";
|
||||
import Crossfilter from "../util/typedCrossfilter";
|
||||
import * as globals from "../globals";
|
||||
|
||||
|
||||
+16
-23
@@ -1,9 +1,9 @@
|
||||
// jshint esversion: 6
|
||||
var createCamera = require("orbit-camera");
|
||||
var createScroll = require("scroll-speed");
|
||||
var mp = require("mouse-position");
|
||||
var mb = require("mouse-pressed");
|
||||
var key = require("key-pressed");
|
||||
const createCamera = require("orbit-camera");
|
||||
const createScroll = require("scroll-speed");
|
||||
const mp = require("mouse-position");
|
||||
const mb = require("mouse-pressed");
|
||||
const key = require("key-pressed");
|
||||
|
||||
const panSpeed = 0.4;
|
||||
const scaleSpeed = 0.5;
|
||||
@@ -17,20 +17,19 @@ function attachCamera(canvas, opts) {
|
||||
opts.scale = opts.scale !== false;
|
||||
opts.rotate = opts.rotate !== false;
|
||||
|
||||
var scroll = createScroll(canvas, opts.scale);
|
||||
var mbut = mb(canvas, opts.rotate);
|
||||
var mpos = mp(canvas);
|
||||
var camera = createCamera([0, 0, 1], [0, 0, -1], [0, 1, 0]);
|
||||
const scroll = createScroll(canvas, opts.scale);
|
||||
const mbut = mb(canvas, opts.rotate);
|
||||
const mpos = mp(canvas);
|
||||
const camera = createCamera([0, 0, 1], [0, 0, -1], [0, 1, 0]);
|
||||
|
||||
camera.tick = tick;
|
||||
|
||||
return camera;
|
||||
|
||||
function tick() {
|
||||
var ctrl = key("<control>") || key("<alt>");
|
||||
var alt = key("<shift>");
|
||||
var height = canvas.height;
|
||||
var width = canvas.width;
|
||||
const ctrl = key("<control>") || key("<alt>");
|
||||
const alt = key("<shift>");
|
||||
const { height, width } = canvas;
|
||||
|
||||
if (opts.rotate && mbut.left && ctrl && !alt) {
|
||||
camera.rotate(
|
||||
@@ -41,23 +40,17 @@ function attachCamera(canvas, opts) {
|
||||
|
||||
if ((opts.pan && mbut.right) || (mbut.left && !ctrl && !alt)) {
|
||||
camera.pan([
|
||||
panSpeed *
|
||||
(mpos[0] - mpos.prev[0]) /
|
||||
width *
|
||||
Math.pow(camera.distance, 1),
|
||||
panSpeed *
|
||||
(mpos[1] - mpos.prev[1]) /
|
||||
height *
|
||||
Math.pow(camera.distance, 1)
|
||||
((panSpeed * (mpos[0] - mpos.prev[0])) / width) * camera.distance,
|
||||
((panSpeed * (mpos[1] - mpos.prev[1])) / height) * camera.distance
|
||||
]);
|
||||
}
|
||||
|
||||
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))) {
|
||||
var d = mpos.y - mpos.prevY;
|
||||
const d = mpos.y - mpos.prevY;
|
||||
if (!d) return;
|
||||
|
||||
camera.distance *= Math.exp(d / height);
|
||||
|
||||
+10
-11
@@ -1,28 +1,27 @@
|
||||
// jshint esversion: 6
|
||||
import { scaleRGB } from "./scaleRGB";
|
||||
import scaleRGB from "./scaleRGB";
|
||||
|
||||
// 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 talk about colors by their text description eg, 'rgb(0,0,1)'
|
||||
//
|
||||
const colorCache = new Object(null); // no prototype
|
||||
const colorCache = {};
|
||||
|
||||
function parseColorName(c) {
|
||||
if (c[0] !== "#") {
|
||||
const _c = c.replace(/[^\d,.]/g, "").split(",");
|
||||
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 => {
|
||||
var cv = colorCache[c];
|
||||
export default c => {
|
||||
let cv = colorCache[c];
|
||||
if (!cv) {
|
||||
cv = parseColorName(c);
|
||||
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
|
||||
// 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 scale = (range[1] - range[0]) / (domain[1] - domain[0]);
|
||||
const rangeStart = range[0];
|
||||
return function(value) {
|
||||
return (value - domainStart) * scale + rangeStart;
|
||||
};
|
||||
return value => (value - domainStart) * scale + rangeStart;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// jshint esversion: 6
|
||||
export const scaleRGB = input => {
|
||||
export default input => {
|
||||
const outputMax = 1;
|
||||
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 (aDepth === 1 && depth === 1) {
|
||||
intervalStart = p[0];
|
||||
[intervalStart] = p;
|
||||
} else if (intervalStart !== undefined) {
|
||||
res.push([intervalStart, p[0]]);
|
||||
intervalStart = undefined;
|
||||
@@ -113,7 +113,7 @@ class PositiveIntervals {
|
||||
const p = points[i];
|
||||
depth += p[2] ? 1 : -1;
|
||||
if (depth === 2) {
|
||||
intervalStart = p[0];
|
||||
[intervalStart] = p;
|
||||
} else if (intervalStart !== undefined) {
|
||||
res.push([intervalStart, p[0]]);
|
||||
intervalStart = undefined;
|
||||
|
||||
Reference in New Issue
Block a user