index.community/frontend/src/components/atoms/GraphKey.tsx

133 lines
3.6 KiB
TypeScript
Raw Normal View History

2019-07-27 17:58:40 +00:00
import { Button, Classes, H5, MenuItem } from "@blueprintjs/core";
2019-07-24 15:51:44 +00:00
import { IconNames } from "@blueprintjs/icons";
import { ItemRenderer, Select } from "@blueprintjs/select";
2019-07-27 17:58:40 +00:00
import * as numeral from "numeral";
2019-07-24 15:51:44 +00:00
import React from "react";
import styled from "styled-components";
2019-07-24 16:25:20 +00:00
import { FloatingCard, InstanceType } from ".";
2019-07-27 17:58:40 +00:00
import { QUANTITATIVE_COLOR_SCHEME } from "../../constants";
import { IColorScheme } from "../../types";
2019-07-24 15:51:44 +00:00
2019-07-27 17:58:40 +00:00
const ColorSchemeSelect = Select.ofType<IColorScheme>();
2019-07-24 15:51:44 +00:00
const StyledLi = styled.li`
margin-top: 2px;
`;
const StyledKeyContainer = styled.div`
margin-top: 10px;
`;
2019-07-27 17:58:40 +00:00
const ColorKeyContainer = styled.div`
display: flex;
flex-direction: row;
height: 100px;
`;
const ColorBarContainer = styled.div`
width: 10px;
display: flex;
flex-direction: column;
margin-right: 10px;
`;
interface IColorBarProps {
color: string;
}
const ColorBar = styled.div<IColorBarProps>`
width: 10px;
background-color: ${props => props.color};
flex: 1;
`;
const TextContainer = styled.div`
display: flex;
flex-direction: column;
justify-content: space-between;
`;
2019-07-24 15:51:44 +00:00
interface IGraphKeyProps {
2019-07-27 17:58:40 +00:00
current?: IColorScheme;
colorSchemes: IColorScheme[];
ranges?: { [key: string]: [number, number] };
onItemSelect: (colorScheme?: IColorScheme) => void;
2019-07-24 15:51:44 +00:00
}
2019-07-27 17:58:40 +00:00
const GraphKey: React.FC<IGraphKeyProps> = ({ current, colorSchemes, ranges, onItemSelect }) => {
2019-07-24 15:51:44 +00:00
const unsetColorScheme = () => {
onItemSelect(undefined);
};
2019-07-27 17:58:40 +00:00
let key;
if (current) {
if (current.type === "qualitative") {
key = renderQualitativeKey(current.values);
} else if (current.type === "quantitative") {
key = renderQuantitativeKey(ranges![current.cytoscapeDataKey]);
}
}
2019-07-24 15:51:44 +00:00
return (
<FloatingCard>
<H5>Color coding</H5>
<ColorSchemeSelect
activeItem={current}
filterable={false}
items={colorSchemes}
itemRenderer={renderItem}
onItemSelect={onItemSelect}
popoverProps={{ minimal: true }}
>
<Button
text={(current && current.name) || "Select..."}
icon={IconNames.TINT}
rightIcon={IconNames.CARET_DOWN}
2020-04-21 19:31:29 +00:00
tabIndex={-1}
/>
<Button
icon={IconNames.SMALL_CROSS}
minimal={true}
onClick={unsetColorScheme}
disabled={!current}
tabIndex={-1}
2019-07-24 15:51:44 +00:00
/>
</ColorSchemeSelect>
2019-07-27 17:58:40 +00:00
<br />
{!!current && !!key && (
<>
{current.description && <span className={Classes.TEXT_MUTED}>{current.description}</span>}
<StyledKeyContainer>{key}</StyledKeyContainer>
</>
2019-07-24 15:51:44 +00:00
)}
</FloatingCard>
);
};
2019-07-27 17:58:40 +00:00
const renderItem: ItemRenderer<IColorScheme> = (colorScheme, { handleClick, modifiers }) => {
2019-07-24 15:51:44 +00:00
if (!modifiers.matchesPredicate) {
return null;
}
return <MenuItem active={modifiers.active} key={colorScheme.name} onClick={handleClick} text={colorScheme.name} />;
};
2019-07-27 17:58:40 +00:00
const renderQualitativeKey = (values: string[]) => (
<ul className={Classes.LIST_UNSTYLED}>
{values.map(v => (
<StyledLi key={v}>
<InstanceType type={v} />
</StyledLi>
))}
</ul>
);
const renderQuantitativeKey = (range: number[]) => {
const [min, max] = range;
return (
<ColorKeyContainer>
<ColorBarContainer>
{QUANTITATIVE_COLOR_SCHEME.map((color, idx) => (
<ColorBar color={color} key={color} />
2019-07-27 17:58:40 +00:00
))}
</ColorBarContainer>
<TextContainer>
<span className={Classes.TEXT_SMALL}>{numeral.default(min).format("0")}</span>
<span className={Classes.TEXT_SMALL}>{numeral.default(max).format("0")}</span>
</TextContainer>
</ColorKeyContainer>
);
};
2019-07-24 15:51:44 +00:00
export default GraphKey;