mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-26 10:18:12 +08:00
+1
-4
@@ -33,7 +33,4 @@ npm-debug.log
|
||||
*.idea*
|
||||
__pycache__
|
||||
*.DS_Store*
|
||||
|
||||
|
||||
|
||||
|
||||
data
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
<title>cellxgene</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,400i,700" rel="stylesheet">
|
||||
<style>
|
||||
html, body, p, h1, h2, h3, h4, h5, h6, span, button, input, label, text {
|
||||
html, body, p, h1, h2, h3, h4, h5, h6, span, button, input, label, text, div {
|
||||
font-family: 'Roboto Condensed','Helvetica Neue','Helvetica','Arial',sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<title>cellxgene</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,400i,700" rel="stylesheet">
|
||||
<style>
|
||||
html, body, p, h1, h2, h3, h4, h5, h6, span, button, input, label, text {
|
||||
html, body, p, h1, h2, h3, h4, h5, h6, span, button, input, label, text, div {
|
||||
font-family: 'Roboto Condensed','Helvetica Neue','Helvetica','Arial',sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ https://bl.ocks.org/SpaceActuary/2f004899ea1b2bd78d6f1dbb2febf771
|
||||
// jshint esversion: 6
|
||||
import React from "react";
|
||||
import _ from "lodash";
|
||||
import { Button, ButtonGroup } from "@blueprintjs/core";
|
||||
import { connect } from "react-redux";
|
||||
import { FaPaintBrush } from "react-icons/fa";
|
||||
import * as d3 from "d3";
|
||||
import memoize from "memoize-one";
|
||||
import { kvCache } from "../../util/stateManager";
|
||||
@@ -74,7 +74,7 @@ class HistogramBrush extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.width = 300;
|
||||
this.width = 340;
|
||||
this.height = 100;
|
||||
this.marginBottom = 20;
|
||||
|
||||
@@ -156,8 +156,7 @@ class HistogramBrush extends React.Component {
|
||||
|
||||
d3.select(svgRef)
|
||||
.selectAll(".axis--x text")
|
||||
.style("fill", "rgb(80,80,80)")
|
||||
.style("font-size", 12);
|
||||
.style("fill", "rgb(80,80,80)");
|
||||
|
||||
d3.select(svgRef)
|
||||
.selectAll(".axis--x path")
|
||||
@@ -234,110 +233,62 @@ class HistogramBrush extends React.Component {
|
||||
set1AvgExp,
|
||||
set2AvgExp,
|
||||
scatterplotXXaccessor,
|
||||
scatterplotYYaccessor
|
||||
scatterplotYYaccessor,
|
||||
zebra
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10,
|
||||
position: "flex"
|
||||
}}
|
||||
id={`histogram_${field}`}
|
||||
style={{
|
||||
padding: globals.leftSidebarSectionPadding,
|
||||
backgroundColor: zebra ? globals.lightestGrey : "white"
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<span style={{ fontSize: globals.tiniestFontSize }}> {field} </span>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
{isDiffExp ? (
|
||||
<span>
|
||||
<span
|
||||
style={{ marginRight: 7 }}
|
||||
className="bp3-icon-standard bp3-icon-scatter-plot"
|
||||
/>
|
||||
<ButtonGroup style={{ marginRight: 7 }}>
|
||||
<Button
|
||||
onClick={this.handleSetGeneAsScatterplotX(field).bind(this)}
|
||||
active={scatterplotXXaccessor === field}
|
||||
intent={scatterplotXXaccessor === field ? "primary" : "none"}
|
||||
>
|
||||
plot x
|
||||
</Button>
|
||||
<Button
|
||||
onClick={this.handleSetGeneAsScatterplotY(field).bind(this)}
|
||||
active={scatterplotYYaccessor === field}
|
||||
intent={scatterplotYYaccessor === field ? "primary" : "none"}
|
||||
>
|
||||
plot y
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</span>
|
||||
) : null}
|
||||
{isUserDefined ? (
|
||||
<span
|
||||
<Button
|
||||
minimal
|
||||
onClick={this.removeHistogram.bind(this)}
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
color: globals.blue,
|
||||
cursor: "pointer",
|
||||
marginLeft: 7
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</span>
|
||||
) : null}
|
||||
{isDiffExp ? (
|
||||
<span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
marginLeft: 7
|
||||
}}
|
||||
>
|
||||
<strong>1:</strong>
|
||||
{` ${set1AvgExp.toPrecision(2)}`}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
marginLeft: 7,
|
||||
backgroundColor: globals.lighterGrey,
|
||||
padding: 2
|
||||
}}
|
||||
>
|
||||
<strong>2:</strong>
|
||||
{` ${set2AvgExp.toPrecision(2)}`}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: globals.tiniestFontSize,
|
||||
marginLeft: 7
|
||||
}}
|
||||
>
|
||||
{`Av. Diff: ${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>
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
onClick={this.handleColorAction.bind(this)}
|
||||
active={colorAccessor === field}
|
||||
intent={colorAccessor === field ? "primary" : "none"}
|
||||
icon="tint"
|
||||
/>
|
||||
</div>
|
||||
<svg
|
||||
width={this.width}
|
||||
@@ -346,22 +297,46 @@ class HistogramBrush extends React.Component {
|
||||
this.drawHistogram(svgRef);
|
||||
}}
|
||||
/>
|
||||
<span
|
||||
onClick={this.handleColorAction.bind(this)}
|
||||
<div
|
||||
style={{
|
||||
fontSize: 14,
|
||||
marginLeft: 4,
|
||||
// padding: this.props.colorAccessor === this.props.field ? 3 : "auto",
|
||||
borderRadius: 3,
|
||||
color: colorAccessor === field ? globals.brightBlue : "black",
|
||||
// backgroundColor: this.props.colorAccessor === this.props.field ? globals.brightBlue : "inherit",
|
||||
position: "relative",
|
||||
top: -29,
|
||||
cursor: "pointer"
|
||||
display: "flex",
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
<FaPaintBrush />
|
||||
</span>
|
||||
<span style={{ fontStyle: "italic" }}>{field}</span>
|
||||
</div>
|
||||
|
||||
{isDiffExp ? (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "baseline"
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
<strong>1:</strong>
|
||||
{` ${set1AvgExp.toPrecision(2)}`}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
marginLeft: 7,
|
||||
backgroundColor: globals.lighterGrey,
|
||||
padding: 2
|
||||
}}
|
||||
>
|
||||
<strong>2:</strong>
|
||||
{` ${set2AvgExp.toPrecision(2)}`}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
marginLeft: 7
|
||||
}}
|
||||
>
|
||||
{`Av. Diff: ${avgDiff.toFixed(2)}`}
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from "react";
|
||||
import _ from "lodash";
|
||||
import { connect } from "react-redux";
|
||||
import { FaChevronRight, FaChevronDown, FaPaintBrush } from "react-icons/fa";
|
||||
import { FaChevronRight, FaChevronDown } from "react-icons/fa";
|
||||
import memoize from "memoize-one";
|
||||
import { Button } from "@blueprintjs/core";
|
||||
|
||||
import * as globals from "../../globals";
|
||||
import Value from "./value";
|
||||
@@ -119,55 +120,58 @@ class Category extends React.Component {
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "baseline"
|
||||
}}
|
||||
>
|
||||
<label className="bp3-control bp3-checkbox">
|
||||
<input
|
||||
onChange={this.handleToggleAllClick.bind(this)}
|
||||
ref={el => {
|
||||
this.checkbox = el;
|
||||
return el;
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "baseline"
|
||||
}}
|
||||
>
|
||||
<label className="bp3-control bp3-checkbox">
|
||||
<input
|
||||
onChange={this.handleToggleAllClick.bind(this)}
|
||||
ref={el => {
|
||||
this.checkbox = el;
|
||||
return el;
|
||||
}}
|
||||
checked={isChecked}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span className="bp3-control-indicator" />
|
||||
{""}
|
||||
</label>
|
||||
|
||||
<span
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
display: "inline-block"
|
||||
}}
|
||||
checked={isChecked}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span className="bp3-control-indicator" />
|
||||
{""}
|
||||
</label>
|
||||
|
||||
<span
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
display: "inline-block"
|
||||
}}
|
||||
onClick={() => {
|
||||
this.setState({ isExpanded: !isExpanded });
|
||||
}}
|
||||
>
|
||||
{metadataField}
|
||||
{isExpanded ? (
|
||||
<FaChevronDown style={{ fontSize: 10, marginLeft: 5 }} />
|
||||
) : (
|
||||
<FaChevronRight style={{ fontSize: 10, marginLeft: 5 }} />
|
||||
)}
|
||||
</span>
|
||||
|
||||
<span
|
||||
onClick={() => {
|
||||
this.setState({ isExpanded: !isExpanded });
|
||||
}}
|
||||
>
|
||||
{metadataField}
|
||||
{isExpanded ? (
|
||||
<FaChevronDown style={{ fontSize: 10, marginLeft: 5 }} />
|
||||
) : (
|
||||
<FaChevronRight style={{ fontSize: 10, marginLeft: 5 }} />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
<Button
|
||||
onClick={this.handleColorChange.bind(this)}
|
||||
style={{
|
||||
marginLeft: 4,
|
||||
color:
|
||||
colorAccessor === metadataField ? globals.brightBlue : "black",
|
||||
display: "inline-block",
|
||||
cursor: "pointer"
|
||||
}}
|
||||
>
|
||||
<FaPaintBrush style={{ fontSize: 12, marginLeft: 10 }} />
|
||||
</span>
|
||||
active={colorAccessor === metadataField}
|
||||
intent={colorAccessor === metadataField ? "primary" : "none"}
|
||||
icon={"tint"}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ marginLeft: 26 }}>
|
||||
{isExpanded ? this.renderCategoryItems() : null}
|
||||
</div>
|
||||
<div style={{ marginLeft: 26 }}>{isExpanded ? this.renderCategoryItems() : null}</div>
|
||||
<div>
|
||||
{isExpanded && isTruncated ? (
|
||||
<p style={{ paddingLeft: 15 }}>... truncated list ...</p>
|
||||
|
||||
@@ -48,16 +48,16 @@ class Continuous extends React.Component {
|
||||
this.continuousChecked = true; /* only do this once */
|
||||
}
|
||||
|
||||
/* initial value for iterator to simulate index, ranges is an object */
|
||||
let zebra = -1;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
padding: globals.leftSidebarSectionPadding
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
{this.hasContinuous ? (
|
||||
<p
|
||||
style={Object.assign({}, globals.leftSidebarSectionHeading, {
|
||||
marginTop: 40
|
||||
marginTop: 40,
|
||||
paddingLeft: globals.leftSidebarSectionPadding
|
||||
})}
|
||||
>
|
||||
Continuous metadata
|
||||
@@ -65,12 +65,14 @@ class Continuous extends React.Component {
|
||||
) : null}
|
||||
{_.map(ranges, (value, key) => {
|
||||
const isColorField = key.includes("color") || key.includes("Color");
|
||||
zebra += 1;
|
||||
if (value.range && key !== "name" && !isColorField) {
|
||||
return (
|
||||
<HistogramBrush
|
||||
key={key}
|
||||
field={key}
|
||||
isObs
|
||||
zebra={zebra % 2 === 0}
|
||||
fieldValues={obsAnnotations}
|
||||
ranges={value.range}
|
||||
handleColorAction={this.handleColorAction(key).bind(this)}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { interpolateViridis } from "d3-scale-chromatic";
|
||||
|
||||
// create continuous color legend
|
||||
// http://bl.ocks.org/syntagmatic/e8ccca52559796be775553b467593a9f
|
||||
const continuous = (selectorId, colorscale, colorAccessor) => {
|
||||
const continuous = (selectorId, colorscale) => {
|
||||
const legendheight = 200;
|
||||
const legendwidth = 80;
|
||||
const margin = { top: 10, right: 60, bottom: 10, left: 2 };
|
||||
|
||||
@@ -3,7 +3,6 @@ import React from "react";
|
||||
import _ from "lodash";
|
||||
import { Button } from "@blueprintjs/core";
|
||||
import { connect } from "react-redux";
|
||||
import * as globals from "../../globals";
|
||||
|
||||
@connect()
|
||||
class CellSetButton extends React.Component {
|
||||
|
||||
@@ -37,6 +37,9 @@ class Expression extends React.Component {
|
||||
type: "clear differential expression",
|
||||
diffExp: differential.diffExp
|
||||
});
|
||||
dispatch({
|
||||
type: "clear scatterplot"
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -47,7 +50,13 @@ class Expression extends React.Component {
|
||||
const haveBothCellSets =
|
||||
!!differential.celllist1 && !!differential.celllist2;
|
||||
return (
|
||||
<div style={{ marginRight: 10, marginBottom: 10 }}>
|
||||
<div
|
||||
style={{
|
||||
marginRight: 10,
|
||||
marginBottom: 10,
|
||||
paddingLeft: globals.leftSidebarSectionPadding
|
||||
}}
|
||||
>
|
||||
<CellSetButton {...this.props} eitherCellSetOneOrTwo={1} />
|
||||
<CellSetButton {...this.props} eitherCellSetOneOrTwo={2} />
|
||||
{!differential.diffExp ? (
|
||||
@@ -55,6 +64,7 @@ class Expression extends React.Component {
|
||||
style={{ marginTop: 10 }}
|
||||
disabled={!haveBothCellSets}
|
||||
intent="primary"
|
||||
fill
|
||||
type="button"
|
||||
onClick={this.computeDiffExp.bind(this)}
|
||||
>
|
||||
@@ -64,6 +74,7 @@ class Expression extends React.Component {
|
||||
{differential.diffExp ? (
|
||||
<Button
|
||||
type="button"
|
||||
fill
|
||||
style={{ marginTop: 10 }}
|
||||
intent="warning"
|
||||
onClick={this.clearDifferentialExpression.bind(this)}
|
||||
|
||||
@@ -76,14 +76,22 @@ class GeneExpression extends React.Component {
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
padding: globals.leftSidebarSectionPadding,
|
||||
marginTop: 30
|
||||
}}
|
||||
>
|
||||
<p style={globals.leftSidebarSectionHeading}>Custom genes</p>
|
||||
<div style={{ marginTop: 11 }} className="bp3-control-group">
|
||||
<div className="bp3-input-group">
|
||||
<span className="bp3-icon bp3-icon-symbol-cross" />
|
||||
<p
|
||||
style={Object.assign({}, globals.leftSidebarSectionHeading, {
|
||||
paddingLeft: globals.leftSidebarSectionPadding,
|
||||
margin: 0
|
||||
})}
|
||||
>
|
||||
Custom genes
|
||||
</p>
|
||||
<div
|
||||
style={{ padding: globals.leftSidebarSectionPadding }}
|
||||
className="bp3-control-group"
|
||||
>
|
||||
<div className="bp3-input-group bp3-fill">
|
||||
<input
|
||||
onKeyDown={this.keyPress.bind(this)}
|
||||
onChange={e => {
|
||||
@@ -105,7 +113,7 @@ class GeneExpression extends React.Component {
|
||||
</button>
|
||||
</div>
|
||||
{world && userDefinedGenes.length > 0
|
||||
? _.map(userDefinedGenes, geneName => {
|
||||
? _.map(userDefinedGenes, (geneName, index) => {
|
||||
const values = world.varDataCache[geneName];
|
||||
if (!values) {
|
||||
return null;
|
||||
@@ -114,6 +122,7 @@ class GeneExpression extends React.Component {
|
||||
<HistogramBrush
|
||||
key={geneName}
|
||||
field={geneName}
|
||||
zebra={index % 2 === 0}
|
||||
ranges={d3.extent(values)}
|
||||
isUserDefined
|
||||
/>
|
||||
@@ -121,21 +130,18 @@ class GeneExpression extends React.Component {
|
||||
})
|
||||
: null}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
padding: globals.leftSidebarSectionPadding
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<p
|
||||
style={Object.assign({}, globals.leftSidebarSectionHeading, {
|
||||
marginTop: 40
|
||||
marginTop: 40,
|
||||
paddingLeft: globals.leftSidebarSectionPadding
|
||||
})}
|
||||
>
|
||||
Differentially Expressed Genes
|
||||
</p>
|
||||
<ExpressionButtons />
|
||||
{differential.diffExp
|
||||
? _.map(differential.diffExp, value => {
|
||||
? _.map(differential.diffExp, (value, index) => {
|
||||
const annotations = world.varAnnotations[value[0]];
|
||||
const { name } = annotations;
|
||||
const values = world.varDataCache[name];
|
||||
@@ -146,6 +152,7 @@ class GeneExpression extends React.Component {
|
||||
<HistogramBrush
|
||||
key={name}
|
||||
field={name}
|
||||
zebra={index % 2 === 0}
|
||||
ranges={d3.extent(values)}
|
||||
isDiffExp
|
||||
avgDiff={value[1]}
|
||||
|
||||
@@ -96,7 +96,8 @@ class Graph extends React.Component {
|
||||
camera,
|
||||
pointBuffer,
|
||||
colorBuffer,
|
||||
sizeBuffer
|
||||
sizeBuffer,
|
||||
svg
|
||||
} = this.state;
|
||||
|
||||
if (reglRender && this.reglRenderState === "rendering" && mode !== "zoom") {
|
||||
@@ -183,19 +184,19 @@ class Graph extends React.Component {
|
||||
prevProps.responsive.height !== responsive.height ||
|
||||
prevProps.responsive.width !== responsive.width ||
|
||||
/* first time */
|
||||
(responsive.height && responsive.width && !this.state.svg)
|
||||
(responsive.height && responsive.width && !svg)
|
||||
) {
|
||||
/* clear out whatever was on the div, even if nothing, but usually the brushes etc */
|
||||
d3.select("#graphAttachPoint")
|
||||
.selectAll("svg")
|
||||
.remove();
|
||||
const { svg: newSvg, brush, brushContainer } = setupSVGandBrushElements(
|
||||
const { svg: newSvg, brush } = setupSVGandBrushElements(
|
||||
this.handleBrushSelectAction.bind(this),
|
||||
this.handleBrushDeselectAction.bind(this),
|
||||
responsive,
|
||||
this.graphPaddingTop
|
||||
);
|
||||
this.setState({ svg: newSvg, brush, brushContainer });
|
||||
this.setState({ svg: newSvg, brush });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,7 @@ import DynamicScatterplot from "./scatterplot/scatterplot";
|
||||
scatterplotYYaccessor: state.controls.scatterplotYYaccessor
|
||||
}))
|
||||
class LeftSideBar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
currentTab: "metadata"
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { currentTab } = this.state;
|
||||
const {
|
||||
responsive,
|
||||
datasetTitle,
|
||||
|
||||
@@ -258,6 +258,7 @@ class Scatterplot extends React.Component {
|
||||
.attr("x", 10)
|
||||
.attr("y", 10)
|
||||
.attr("class", "label")
|
||||
.style("font-style", "italic")
|
||||
.text(scatterplotYYaccessor);
|
||||
|
||||
svg
|
||||
@@ -266,6 +267,7 @@ class Scatterplot extends React.Component {
|
||||
.attr("y", height - 10)
|
||||
.attr("text-anchor", "end")
|
||||
.attr("class", "label")
|
||||
.style("font-style", "italic")
|
||||
.text(scatterplotXXaccessor);
|
||||
}
|
||||
|
||||
@@ -285,7 +287,6 @@ class Scatterplot extends React.Component {
|
||||
id="scatterplot_wrapper"
|
||||
>
|
||||
<ButtonGroup
|
||||
minimal
|
||||
style={{
|
||||
position: "absolute",
|
||||
right: 5,
|
||||
@@ -294,14 +295,16 @@ class Scatterplot extends React.Component {
|
||||
>
|
||||
<Button
|
||||
type="button"
|
||||
icon={minimized ? "plus" : "minus"}
|
||||
minimal
|
||||
onClick={() => {
|
||||
this.setState({ minimized: !minimized });
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{minimized ? "show scatterplot" : "hide"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
icon="cross"
|
||||
minimal
|
||||
onClick={() => {
|
||||
dispatch({
|
||||
type: "clear scatterplot"
|
||||
@@ -310,7 +313,9 @@ class Scatterplot extends React.Component {
|
||||
type: "reset colorscale"
|
||||
});
|
||||
}}
|
||||
/>
|
||||
>
|
||||
remove
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<div
|
||||
className={styles.scatterplot}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Provider } from "react-redux";
|
||||
import { FocusStyleManager } from "@blueprintjs/core";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
@@ -10,6 +11,8 @@ import "./index.css";
|
||||
import App from "./components/app";
|
||||
import store from "./reducers";
|
||||
|
||||
FocusStyleManager.onlyShowFocusOnTabs();
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
|
||||
Reference in New Issue
Block a user