mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-22 17:58:11 +08:00
Remove heatmap, add diffexp info to histograms (#339)
* Create Release_Validation_Recipe.md * compose middle ware for redux devtools * update package.json and lock * remove heatmap, add to left side bar * redux devtools extension
This commit is contained in:
Generated
+34
-29
@@ -2054,7 +2054,7 @@
|
||||
},
|
||||
"babel-plugin-syntax-object-rest-spread": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
|
||||
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -2489,7 +2489,7 @@
|
||||
},
|
||||
"browserify-aes": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
|
||||
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -2526,7 +2526,7 @@
|
||||
},
|
||||
"browserify-rsa": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
|
||||
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -2580,7 +2580,7 @@
|
||||
},
|
||||
"buffer": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
|
||||
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3258,7 +3258,7 @@
|
||||
},
|
||||
"create-hash": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
|
||||
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3271,7 +3271,7 @@
|
||||
},
|
||||
"create-hmac": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
|
||||
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3945,7 +3945,7 @@
|
||||
},
|
||||
"diffie-hellman": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
|
||||
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -4522,7 +4522,7 @@
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
|
||||
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -4699,7 +4699,7 @@
|
||||
},
|
||||
"events": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
|
||||
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
|
||||
},
|
||||
"evp_bytestokey": {
|
||||
@@ -4993,7 +4993,7 @@
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -5717,7 +5717,7 @@
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -6096,7 +6096,7 @@
|
||||
},
|
||||
"html-webpack-plugin": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "http://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
|
||||
"integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -6172,7 +6172,7 @@
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
|
||||
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -6395,7 +6395,7 @@
|
||||
},
|
||||
"is-builtin-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
|
||||
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -7394,7 +7394,7 @@
|
||||
},
|
||||
"json5": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -7484,7 +7484,7 @@
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
||||
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -7813,7 +7813,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -7938,7 +7938,7 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -7983,7 +7983,7 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -9695,7 +9695,7 @@
|
||||
},
|
||||
"parse-asn1": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
|
||||
"integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -10291,7 +10291,7 @@
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "5.0.7",
|
||||
"resolved": "http://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
|
||||
"integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^2.5.0",
|
||||
@@ -10355,7 +10355,7 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -10698,6 +10698,11 @@
|
||||
"symbol-observable": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"redux-devtools-extension": {
|
||||
"version": "2.13.5",
|
||||
"resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.5.tgz",
|
||||
"integrity": "sha512-QQ9BRy77oURHMdGys9rfQcCQDzXZ1T4oW+eUyE5Cg7DNVau69HJzc4YNDMOmpi0Dzpi1zOQgQ2rUpgJta4Lfqg=="
|
||||
},
|
||||
"redux-thunk": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||
@@ -11368,7 +11373,7 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -11555,7 +11560,7 @@
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.11",
|
||||
"resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
|
||||
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -12009,7 +12014,7 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -12245,7 +12250,7 @@
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -12884,7 +12889,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -13542,7 +13547,7 @@
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -13650,7 +13655,7 @@
|
||||
},
|
||||
"yargs": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
|
||||
"integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"react-icons": "^3.2.0",
|
||||
"react-redux": "^5.0.6",
|
||||
"redux": "^4.0.1",
|
||||
"redux-devtools-extension": "^2.13.5",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"regl": "^1.3.1",
|
||||
"scroll-speed": "^1.0.0",
|
||||
|
||||
@@ -16,7 +16,10 @@ import actions from "../../actions";
|
||||
|
||||
@connect(state => ({
|
||||
world: state.controls.world,
|
||||
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
||||
scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
|
||||
crossfilter: state.controls.crossfilter,
|
||||
differential: state.differential,
|
||||
initializeRanges: _.get(state.controls.world, "summary.obs"),
|
||||
colorAccessor: state.controls.colorAccessor,
|
||||
colorScale: state.controls.colorScale,
|
||||
@@ -208,8 +211,38 @@ class HistogramBrush extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleSetGeneAsScatterplotX() {
|
||||
return () => {
|
||||
const { dispatch, field } = this.props;
|
||||
dispatch({
|
||||
type: "set scatterplot x",
|
||||
data: field
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
handleSetGeneAsScatterplotY() {
|
||||
return () => {
|
||||
const { dispatch, field } = this.props;
|
||||
dispatch({
|
||||
type: "set scatterplot y",
|
||||
data: field
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { field, ranges, colorAccessor, isUserDefined } = this.props;
|
||||
const {
|
||||
field,
|
||||
colorAccessor,
|
||||
isUserDefined,
|
||||
isDiffExp,
|
||||
diffExp_avgDiff,
|
||||
diffExp_set1AvgExp,
|
||||
diffExp_set2AvgExp,
|
||||
scatterplotXXaccessor,
|
||||
scatterplotYYaccessor
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -234,6 +267,84 @@ class HistogramBrush extends React.Component {
|
||||
remove
|
||||
</span>
|
||||
) : null}
|
||||
{isDiffExp ? (
|
||||
<span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
marginLeft: 7
|
||||
}}
|
||||
>
|
||||
<strong>1:</strong>
|
||||
{` ${diffExp_set1AvgExp.toPrecision(2)}`}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
marginLeft: 7,
|
||||
backgroundColor: globals.lighterGrey,
|
||||
padding: 2
|
||||
}}
|
||||
>
|
||||
<strong>2:</strong>
|
||||
{` ${diffExp_set2AvgExp.toPrecision(2)}`}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
marginLeft: 7
|
||||
}}
|
||||
>
|
||||
{`Av. Diff: ${diffExp_avgDiff.toFixed(2)}`}
|
||||
</span>
|
||||
<span
|
||||
onClick={this.handleSetGeneAsScatterplotX(field).bind(this)}
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color:
|
||||
scatterplotXXaccessor === field
|
||||
? "white"
|
||||
: globals.brightBlue,
|
||||
cursor: "pointer",
|
||||
position: "relative",
|
||||
top: 1,
|
||||
fontWeight: 700,
|
||||
marginRight: 4,
|
||||
borderRadius: 3,
|
||||
padding: "2px 3px",
|
||||
backgroundColor:
|
||||
scatterplotXXaccessor === field
|
||||
? globals.brightBlue
|
||||
: "inherit"
|
||||
}}
|
||||
>
|
||||
X
|
||||
</span>
|
||||
<span
|
||||
onClick={this.handleSetGeneAsScatterplotY(field).bind(this)}
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color:
|
||||
scatterplotYYaccessor === field
|
||||
? "white"
|
||||
: globals.brightBlue,
|
||||
cursor: "pointer",
|
||||
position: "relative",
|
||||
top: 1,
|
||||
fontWeight: 700,
|
||||
marginRight: 4,
|
||||
borderRadius: 3,
|
||||
padding: "2px 3px",
|
||||
backgroundColor:
|
||||
scatterplotYYaccessor === field
|
||||
? globals.brightBlue
|
||||
: "inherit"
|
||||
}}
|
||||
>
|
||||
Y
|
||||
</span>
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<svg
|
||||
width={this.width}
|
||||
|
||||
@@ -3,9 +3,7 @@ import React from "react";
|
||||
import _ from "lodash";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import { FaChevronRight } from "react-icons/fa";
|
||||
import { FaChevronDown } from "react-icons/fa";
|
||||
import { FaPaintBrush } from "react-icons/fa";
|
||||
import { FaChevronRight, FaChevronDown, FaPaintBrush } from "react-icons/fa";
|
||||
|
||||
import * as globals from "../../globals";
|
||||
import Value from "./value";
|
||||
@@ -126,7 +124,7 @@ class Category extends React.Component {
|
||||
cursor: "pointer",
|
||||
display: "inline-block",
|
||||
position: "relative",
|
||||
top: -1
|
||||
top: 2
|
||||
}}
|
||||
onClick={() => {
|
||||
this.setState({ isExpanded: !isExpanded });
|
||||
@@ -155,7 +153,7 @@ class Category extends React.Component {
|
||||
// backgroundColor: this.props.colorAccessor === this.props.metadataField ? globals.brightBlue : "inherit",
|
||||
display: "inline-block",
|
||||
position: "relative",
|
||||
top: -1,
|
||||
top: 2,
|
||||
cursor: "pointer"
|
||||
}}
|
||||
>
|
||||
@@ -196,6 +194,7 @@ class Categories extends React.Component {
|
||||
// overflow: "auto",
|
||||
}}
|
||||
>
|
||||
<p> Categorical Metadata </p>
|
||||
{_.map(ranges, (value, key) => {
|
||||
const isColorField = key.includes("color") || key.includes("Color");
|
||||
if (value.options && !isColorField && key !== "name") {
|
||||
|
||||
@@ -37,8 +37,6 @@ class Continuous extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate() {}
|
||||
|
||||
render() {
|
||||
const { ranges, obsAnnotations, schema } = this.props;
|
||||
if (schema && !this.continuousChecked) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from "react";
|
||||
import _ from "lodash";
|
||||
import memoize from "memoize-one";
|
||||
import { connect } from "react-redux";
|
||||
import ReactAutocomplete from "react-autocomplete"; /* http://emilebres.github.io/react-virtualized-checkbox/ */
|
||||
// import ReactAutocomplete from "react-autocomplete"; /* http://emilebres.github.io/react-virtualized-checkbox/ */
|
||||
import getContrast from "font-color-contrast"; // https://www.npmjs.com/package/font-color-contrast
|
||||
import { FaPaintBrush } from "react-icons/fa";
|
||||
import * as d3 from "d3";
|
||||
|
||||
@@ -93,6 +93,8 @@ class GeneExpression extends React.Component {
|
||||
style={{
|
||||
display: "inline-block",
|
||||
marginLeft: 7,
|
||||
position: "relative",
|
||||
top: 5,
|
||||
color: globals.brightBlue,
|
||||
fontSize: 22
|
||||
}}
|
||||
@@ -135,6 +137,9 @@ class GeneExpression extends React.Component {
|
||||
field={name}
|
||||
ranges={d3.extent(values)}
|
||||
isDiffExp
|
||||
diffExp_avgDiff={value[1]}
|
||||
diffExp_set1AvgExp={value[4]}
|
||||
diffExp_set2AvgExp={value[5]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -393,7 +393,9 @@ class Graph extends React.Component {
|
||||
border:
|
||||
mode === "brush" ? "1px solid black" : "1px solid white",
|
||||
backgroundColor: "white",
|
||||
padding: 5,
|
||||
padding: "5px 5px 2px 5px",
|
||||
position: "relative",
|
||||
top: 2,
|
||||
marginRight: 10,
|
||||
borderRadius: 3
|
||||
}}
|
||||
@@ -413,7 +415,9 @@ class Graph extends React.Component {
|
||||
border:
|
||||
mode === "zoom" ? "1px solid black" : "1px solid white",
|
||||
backgroundColor: "white",
|
||||
padding: 5,
|
||||
padding: "5px 5px 2px 5px",
|
||||
position: "relative",
|
||||
top: 2,
|
||||
marginRight: 10,
|
||||
borderRadius: 3
|
||||
}}
|
||||
|
||||
@@ -12,7 +12,9 @@ import DynamicScatterplot from "./scatterplot/scatterplot";
|
||||
|
||||
@connect(state => ({
|
||||
responsive: state.responsive,
|
||||
datasetTitle: _.get(state.config, "displayNames.dataset")
|
||||
datasetTitle: _.get(state.config, "displayNames.dataset"),
|
||||
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
|
||||
scatterplotYYaccessor: state.controls.scatterplotYYaccessor
|
||||
}))
|
||||
class LeftSideBar extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -24,86 +26,48 @@ class LeftSideBar extends React.Component {
|
||||
|
||||
render() {
|
||||
const { currentTab } = this.state;
|
||||
const { responsive, datasetTitle } = this.props;
|
||||
const {
|
||||
responsive,
|
||||
datasetTitle,
|
||||
scatterplotXXaccessor,
|
||||
scatterplotYYaccessor
|
||||
} = this.props;
|
||||
|
||||
/*
|
||||
this magic number should be made less fragile,
|
||||
if cellxgene logo or tabs change, this must as well
|
||||
*/
|
||||
const metadataSectionPadding = currentTab === "metadata" ? 88 : 450;
|
||||
const metadataSectionPadding =
|
||||
scatterplotXXaccessor && scatterplotYYaccessor ? 450 : 0;
|
||||
return (
|
||||
<div style={{ position: "fixed" }}>
|
||||
<p
|
||||
style={{
|
||||
margin: 10,
|
||||
position: "fixed",
|
||||
left: responsive.width / 2,
|
||||
top: 14,
|
||||
margin: 0,
|
||||
fontSize: 24,
|
||||
color: globals.lightGrey,
|
||||
color: globals.darkerGrey,
|
||||
fontWeight: 700,
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
cellxgene
|
||||
cellxgene:
|
||||
{datasetTitle}
|
||||
</p>
|
||||
<div style={{ padding: 10 }}>
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
padding: "none",
|
||||
outline: 0,
|
||||
fontSize: 14,
|
||||
fontWeight: currentTab === "metadata" ? 700 : 400,
|
||||
fontStyle: currentTab === "metadata" ? "inherit" : "italic",
|
||||
cursor: "pointer",
|
||||
border: "none",
|
||||
backgroundColor: "#FFF",
|
||||
borderTop: "none",
|
||||
borderBottom: "none",
|
||||
borderRight: "none",
|
||||
borderLeft: "none"
|
||||
}}
|
||||
onClick={() => {
|
||||
this.setState({ currentTab: "metadata" });
|
||||
}}
|
||||
>
|
||||
Metadata
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
padding: "none",
|
||||
outline: 0,
|
||||
fontSize: 14,
|
||||
fontWeight: currentTab === "expression" ? 700 : 400,
|
||||
fontStyle: currentTab === "expression" ? "inherit" : "italic",
|
||||
cursor: "pointer",
|
||||
border: "none",
|
||||
backgroundColor: "#FFF",
|
||||
borderTop: "none",
|
||||
borderBottom: "none",
|
||||
borderRight: "none",
|
||||
borderLeft: "none"
|
||||
}}
|
||||
onClick={() => {
|
||||
this.setState({ currentTab: "expression" });
|
||||
}}
|
||||
>
|
||||
Expression
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
height: responsive.height - metadataSectionPadding,
|
||||
width: 400,
|
||||
padding: 10,
|
||||
padding: "0px 10px 10px 10px",
|
||||
overflowY: "auto",
|
||||
overflowX: "hidden"
|
||||
}}
|
||||
>
|
||||
{currentTab === "metadata" ? <Categorical /> : null}
|
||||
{currentTab === "metadata" ? <GeneExpression /> : null}
|
||||
{currentTab === "metadata" ? <Continuous /> : null}
|
||||
{currentTab === "expression" ? <Heatmap /> : null}
|
||||
<Categorical />
|
||||
<GeneExpression />
|
||||
<Continuous />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
@@ -112,7 +76,9 @@ class LeftSideBar extends React.Component {
|
||||
left: 0
|
||||
}}
|
||||
>
|
||||
{currentTab === "expression" ? <DynamicScatterplot /> : null}
|
||||
{scatterplotXXaccessor && scatterplotYYaccessor ? (
|
||||
<DynamicScatterplot />
|
||||
) : null}
|
||||
</div>
|
||||
<div style={{ position: "fixed", bottom: 0, right: 0 }}>
|
||||
{currentTab === "metadata" ? <ExpressionButtons /> : null}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { combineReducers, createStore, applyMiddleware } from "redux";
|
||||
import thunk from "redux-thunk";
|
||||
import updateURLMiddleware from "../middleware/updateURLMiddleware";
|
||||
import updateCellColors from "../middleware/updateCellColors";
|
||||
import { composeWithDevTools } from "redux-devtools-extension";
|
||||
|
||||
import config from "./config";
|
||||
import differential from "./differential";
|
||||
@@ -18,8 +19,9 @@ const Reducer = combineReducers({
|
||||
|
||||
const store = createStore(
|
||||
Reducer,
|
||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
|
||||
applyMiddleware(thunk, updateURLMiddleware, updateCellColors)
|
||||
composeWithDevTools(
|
||||
applyMiddleware(thunk, updateURLMiddleware, updateCellColors)
|
||||
)
|
||||
);
|
||||
|
||||
export default store;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# Pre-release Validation Plan
|
||||
_This document contains a general purpose test plan for validating cellxgene prior to release_.
|
||||
|
||||
All steps are expected to pass with no errors or malfunctions. Tester should check:
|
||||
* CLI for errors (eg, build error, engine error)
|
||||
* Browser console for errors
|
||||
* Expected CLI and/or browser UI function
|
||||
|
||||
## [Backend Test](#backend-test)
|
||||
|
||||
### Getting started build & install validation:
|
||||
Goal: validate build, install and example demo correctness, per Getting Started instructions.
|
||||
|
||||
1. Clean clone of the cellxgene repo into a local directory
|
||||
2. Follow build & install instructions from the Getting Started guide
|
||||
* Confirm no build or install errors
|
||||
* Confirm `cellxgene --help` functions correctly
|
||||
3. Follow the example data set demo startup from Getting Started guide and confirm front-end data loads correctly
|
||||
4. Confirm all package (and other) version dependencies are correct and match
|
||||
|
||||
### Tabula Muris
|
||||
Goal: basic functional validation of b/e functions using Tabula Muris data and the scanpy engine.
|
||||
|
||||
1. Precondition: cellxgene built & installed.
|
||||
2. Load the Tabula Muris data set: `cellxgene --title 'T. Muris' scanpy directory-name/`
|
||||
3. Verify all metadata selectors display and have correct type/options:
|
||||
* *TODO:* _need list of metadata and their type_
|
||||
* ...
|
||||
4. Verify default graph display has expected layout. _need screen shot of expected layout_
|
||||
5. Verify selection controls work as expected:
|
||||
* continuous metadata field
|
||||
* categorical metadata field
|
||||
* graph/lasso select
|
||||
6. Verify color by metadata type
|
||||
7. Select two cell sets and confirm differential expression compute succeeds
|
||||
6. Verify expression scatter plot is correct
|
||||
|
||||
|
||||
## [Front-end Compatibility Test](#frontend-compatability-test)
|
||||
Goal: verify front-end UI compatibility with a given browser variant/version/platform.
|
||||
|
||||
1. Start back-end on PBM3K data set
|
||||
2. Load UI
|
||||
3. Verify all major UI modes/functions:
|
||||
* Graph display
|
||||
* Metadata selector display
|
||||
* Title display
|
||||
* Selection - single and multiple fields - correctly display in cluster graph
|
||||
* Regraph & reset function correctly
|
||||
* Differential expression calc & scatter plot display
|
||||
* All graphs maintain consistent selection state
|
||||
* All selection widgets (eg, continuous metadata selector) maintain correct status (consistent with graph displays)
|
||||
4. Verify overall performance is reasonable/interactive
|
||||
5. Verify no errors on CLI or browser console
|
||||
|
||||
|
||||
## [End-to-end Functional Test](#e2e-functional-test)
|
||||
Goal: confirm end-to-end functional behavior is as expected.
|
||||
|
||||
### ScanPy engine
|
||||
|
||||
1. Basic data load and display
|
||||
* ...
|
||||
2. Select & multi-select of metadata and coordinates
|
||||
* ...
|
||||
3. Color by metadata
|
||||
* ...
|
||||
4. Regraph / reset
|
||||
* ...
|
||||
5. Differential expression: scatterplot, top-N genes, etc.
|
||||
* ...
|
||||
6. Color by expression
|
||||
* ...
|
||||
7. Arbitrary gene expression
|
||||
* ...
|
||||
Reference in New Issue
Block a user