higlass
Version:
HiGlass Hi-C / genomic / large data viewer
271 lines (251 loc) • 7.3 kB
JSX
// @ts-nocheck
import PropTypes from 'prop-types';
import React from 'react';
import Dialog from './Dialog';
import HiGlassComponent from './HiGlassComponent';
import SketchInlinePicker from './SketchInlinePicker';
import '../styles/TrackOptions.css';
class HeatmapOptions extends React.Component {
constructor(props) {
super(props);
// props should include the definition of the heatmap data series
this.state = {
colors: props.track.options.colorRange.slice(),
};
}
handleColorsChanged(newColors) {
/*
this.props.onTrackOptionsChanged(Object.assign(this.props.track.options,
{colorRange: newColors}));
*/
this.setState({
colors: newColors,
});
}
handleSubmit() {
const options = this.props.track.options;
options.colorRange = this.state.colors;
this.props.onSubmit(this.props.track.options);
}
/**
* Add a color to the end
*/
handleAddColor() {
this.setState((prevState) => ({
colors: prevState.colors.concat(
prevState.colors[prevState.colors.length - 1],
),
}));
}
/**
* Remove one of the colors from the color map
*/
handleRemoveColor(i) {
this.setState((prevState) => ({
colors: prevState.colors
.slice(0, i)
.concat(prevState.colors.slice(i + 1)),
}));
}
render() {
const track = JSON.parse(JSON.stringify(this.props.track));
const centerTrack = Object.assign(track, {
options: {
colorRange: this.state.colors,
},
});
const mvConfig = {
editable: false,
zoomFixed: true,
views: [
{
uid: `hmo-${this.props.track.uid}`,
initialXDomain: this.props.xScale
? this.props.xScale.domain()
: [0, 1],
initialYDomain: this.props.yScale
? this.props.yScale.domain()
: [0, 1],
tracks: { center: [centerTrack] },
layout: {
x: 0,
y: 0,
h: 12,
w: 12,
i: `hmo-${this.props.track.id}`,
},
},
],
};
const colorFields = this.state.colors
.map((x, i) => {
// only let colors be removed if there's more than two present
const removeButton =
this.state.colors.length > 2 && i === this.state.colors.length - 1 ? (
<div
onClick={() => this.handleRemoveColor(i)}
style={{
background: 'white',
position: 'absolute',
top: 0,
right: 0,
opacity: 1,
width: 14,
height: 14,
borderRadius: 2,
cursor: 'pointer',
}}
>
<svg
height="10px"
style={{
position: 'absolute',
top: 2,
right: 2,
opacity: 0.5,
width: 10,
height: 10,
}}
>
<title>Remove</title>
<use xlinkHref="#cross" />
</svg>
</div>
) : null; // removeButton
return (
// Colors may be repeated, so the array index is the best choice here.
<div
// biome-ignore lint/suspicious/noArrayIndexKey:
key={`l${i}`}
style={{
borderRadius: '1px',
boxShadow: '0 0 0 1px #E5E5E5',
position: 'relative',
outline: 'none',
}}
>
{removeButton}
<SketchInlinePicker
// biome-ignore lint/suspicious/noArrayIndexKey:
key={i}
color={this.state.colors[i]}
onChange={(c) => {
this.setState(
(prevState) => {
const colors = prevState.colors.slice();
colors[i] = c;
return { colors };
},
() => {
this.handleColorsChanged(this.state.colors);
},
);
}}
/>
</div>
);
})
.reverse();
const addButton =
this.state.colors.length < 10 ? (
<div
onClick={this.handleAddColor.bind(this)}
style={{
position: 'relative',
outline: 'none',
height: '25px',
padding: '5px',
background: '#fff',
borderRadius: '1px',
boxShadow: '0 0 0 1px #E5E5E5',
cursor: 'pointer',
}}
>
<div
style={{
textAlign: 'center',
width: '32px',
height: '14px',
}}
>
<svg
height="100%"
style={{
opacity: 0.5,
margin: 'auto',
display: 'block',
}}
width="10px"
>
<title>Add</title>
<use xlinkHref="#plus" />
</svg>
</div>
</div>
) : null; // addButton
return (
<Dialog
okayTitle="Submit"
onCancel={this.props.onCancel}
onOkay={this.handleSubmit.bind(this)}
title="Custom Color Map"
>
<table className="table-track-options">
<thead />
<tbody style={{ verticalAlign: 'top' }}>
<tr>
<td className="td-track-options">
<table>
<tbody>
<tr>
<td className="td-track-options">Preview</td>
</tr>
<tr>
<td
className="td-track-options"
aria-label="Track options"
>
<div style={{ width: 200 }}>
<HiGlassComponent
options={{ bounded: false }}
viewConfig={mvConfig}
/>
</div>
</td>
</tr>
</tbody>
</table>
</td>
<td className="td-track-options">
<table>
<tbody>
<tr>
<td className="td-track-options">Colors</td>
</tr>
<tr>
<td className="td-track-options">
{addButton}
<div style={{ position: 'relative' }}>
{colorFields}
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</Dialog>
);
}
}
HeatmapOptions.propTypes = {
handleCancel: PropTypes.func,
onCancel: PropTypes.func,
onSubmit: PropTypes.func,
track: PropTypes.object,
xScale: PropTypes.object,
yScale: PropTypes.object,
};
export default HeatmapOptions;