diff --git a/components/Defaults.js b/components/Defaults.js index f2685e0..feae24e 100644 --- a/components/Defaults.js +++ b/components/Defaults.js @@ -5,7 +5,9 @@ export const FONTOFFSET = 22 export const AXISCOLOR = '#888888' export const AXISSIZE = 2 export const AXISGAP = 0 -export const MAXNUMAXIS = 5 +export const MAXNUMAXIS = 6 + +export const OPACITYNOTSELECTED = 0.3 export const SVGMARGIN = 20 @@ -18,4 +20,5 @@ export const FEATUREWIDTH = 2 export const FEATURESIZE = 18 export const FEATURESTROKE = 0 export const FEATUREFILLCOLOR = '#E74C3C' +export const FEATUREFILLCOLORS = ['#18247e', '#2870b8', '#4ebcd7', '#bbe4c6'] export const FEATURESTROKECOLOR = '#2C3E50' diff --git a/components/RadialVis/FeatureAxis.js b/components/RadialVis/FeatureAxis.js index f1d596c..a287962 100644 --- a/components/RadialVis/FeatureAxis.js +++ b/components/RadialVis/FeatureAxis.js @@ -1,7 +1,7 @@ import React, { PropTypes } from 'react' import * as d3 from 'd3' import { AXISGAP, AXISCOLOR, AXISSIZE, - FONTCOLOR, FONTSIZE, FONTOFFSET } from '../Defaults' + FONTCOLOR, FONTSIZE, FONTOFFSET, FEATUREFILLCOLOR } from '../Defaults' import Feature from './features/Feature' @@ -98,6 +98,7 @@ class FeatureAxis extends React.Component { .exit() .remove() + // Early Transition Code // if (d !== this.props.d) { // const arc2 = d3.arc() // .innerRadius(r + 10) @@ -119,7 +120,7 @@ class FeatureAxis extends React.Component { // } render() { - const { d, axisGap, geneLength, features } = this.props + const { d, axisGap, geneLength, features, fillColor } = this.props return ( { this.clickArea = c }} /> @@ -132,6 +133,7 @@ class FeatureAxis extends React.Component { stop={x[1]} axisGap={axisGap} geneLength={geneLength} + fillColor={fillColor} /> )) } @@ -147,6 +149,7 @@ FeatureAxis.defaultProps = { axisSize: AXISSIZE, fontColor: FONTCOLOR, fontSize: FONTSIZE, + fillColor: FEATUREFILLCOLOR, } FeatureAxis.propTypes = { @@ -161,6 +164,7 @@ FeatureAxis.propTypes = { axisSize: PropTypes.number, fontColor: PropTypes.string, fontSize: PropTypes.number, + fillColor: PropTypes.string, } export default FeatureAxis diff --git a/components/RadialVis/RadialVis.css b/components/RadialVis/RadialVis.css index 88ecd36..cf886bd 100644 --- a/components/RadialVis/RadialVis.css +++ b/components/RadialVis/RadialVis.css @@ -5,12 +5,14 @@ pointer-events: none; } -.centered { +.svg { top: 50%; left: 50%; transform: translate(-50%, -50%); position: absolute; pointer-events: auto; + user-select: none; + cursor: default; } .hovered { @@ -19,7 +21,7 @@ } .hovered:hover { - opacity: 0.7 !important; + opacity: 0.6 !important; transition: 300ms; transition-timing-function: ease; } diff --git a/components/RadialVis/RadialVis.js b/components/RadialVis/RadialVis.js index d086e68..555ccf8 100644 --- a/components/RadialVis/RadialVis.js +++ b/components/RadialVis/RadialVis.js @@ -1,4 +1,5 @@ import React, { PropTypes } from 'react' +import ReactDOM from 'react-dom' import uID from 'lodash.uniqueid' import MainAxis from './MainAxis' @@ -6,7 +7,7 @@ import FeatureAxis from './FeatureAxis' import style from './RadialVis.css' import ProteinViewer from '../ProteinViewer' -import { SVGMARGIN, MAXNUMAXIS } from '../Defaults' +import { SVGMARGIN, MAXNUMAXIS, FEATUREFILLCOLORS, OPACITYNOTSELECTED } from '../Defaults' import { selectAxis, deselectAxis } from '../../actions/radialVis' /** @@ -23,42 +24,27 @@ class RadialVis extends React.PureComponent { if (feature === visState.selected) { return 1 } - return 0.3 + return OPACITYNOTSELECTED } constructor(props) { super(props) this.calculateRadius = this.calculateRadius.bind(this) this.handleClick = this.handleClick.bind(this) + this.handleDrag = this.handleDrag.bind(this) + this.handleDragClick = this.handleDragClick.bind(this) + + this.handle = [0, 0] + this.oldAngle = 0 + this.drag = false } componentWillMount() { - // TODO probably useless this.setState({ mainAxisKey: uID('mainAxis'), }) } - // componentWillReceiveProps(nextProps) { - // // Calculate new IDs for Features - // if (typeof nextProps.currentSequenceData.uniprot.data !== 'undefined') { - // const currentLength = this.state.featureAxisKeys.length - // const nextLength = nextProps.currentSequenceData.uniprot.data.length - // - // if (nextLength > currentLength) { - // let featureAxisKeys = this.state.featureAxisKeys - // - // for (let i = currentLength - 1; i < nextLength; i++) { - // featureAxisKeys = featureAxisKeys.concat(uID('featureAxis')) - // } - // this.setState(Object.assign({}, this.state, - // { - // featureAxisKeys, - // })) - // } - // } - // } - handleClick(e, feature) { if (feature === this.props.visState.selected) { this.props.dispatch(deselectAxis(feature)) @@ -67,6 +53,28 @@ class RadialVis extends React.PureComponent { } } + handleDrag(e) { + if (this.drag) { + const center = Math.floor(this.calculateRadius(MAXNUMAXIS - 1) / 2) + const v1 = [e.nativeEvent.offsetX - center, e.nativeEvent.offsetY - center] + const v2 = [this.handle[0] - center, this.handle[1] - center] + + let newAngle = Math.atan2(v1[1], v1[0]) + newAngle -= Math.atan2(v2[1], v2[0]) + newAngle += this.oldAngle + + const degree = (newAngle * (360 / (2 * Math.PI))) + ReactDOM.findDOMNode(this.svg).style.transform = `rotate(${degree}deg)` + + this.oldAngle = newAngle + } + } + + handleDragClick(e, mouseDown) { + this.handle = [e.nativeEvent.offsetX, e.nativeEvent.offsetY] + this.drag = mouseDown + } + calculateRadius(i) { const { ui } = this.props const margin = 50 @@ -96,11 +104,17 @@ class RadialVis extends React.PureComponent { } return ( -
+
{ this.svg = c }} + > this.handleDrag(e)} + onMouseDown={e => this.handleDragClick(e, true)} + onMouseUp={e => this.handleDragClick(e, false)} > {uniprot.data && keys.length > 0 && keys.slice(0, MAXNUMAXIS - 1).map((feature, i) => { @@ -121,6 +135,7 @@ class RadialVis extends React.PureComponent { geneLength={uniprot.chainLength} id={feature} name={uniprot.data[feature].name} + fillColor={FEATUREFILLCOLORS[i % FEATUREFILLCOLORS.length]} /> ) diff --git a/package.json b/package.json index a2e9ce4..1fbf317 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "redux-thunk": "^2.1.0", "redux-logger": "^2.7.4", "whatwg-fetch": "^2.0.2", - "lodash.uniqueid": "4.0.1" + "lodash.uniqueid": "^4.0.1" }, "devDependencies": { "assets-webpack-plugin": "^3.5.0", diff --git a/src/main.css b/src/main.css index 07d7a24..6937941 100644 --- a/src/main.css +++ b/src/main.css @@ -3,6 +3,7 @@ body { width: 100%; height: 100%; margin: 0; + overflow: hidden; } .maxSize { diff --git a/yarn.lock b/yarn.lock index 81aaada..d4d7fd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4450,7 +4450,7 @@ lodash.uniq@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash.uniqueid@4.0.1: +lodash.uniqueid@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.uniqueid/-/lodash.uniqueid-4.0.1.tgz#3268f26a7c88e4f4b1758d679271814e31fa5b26" @@ -5734,6 +5734,10 @@ rc@^1.0.1, rc@^1.1.6, rc@~1.1.6: minimist "^1.2.0" strip-json-comments "~1.0.4" +react-clickdrag@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/react-clickdrag/-/react-clickdrag-3.0.2.tgz#54df5f3df6d695c54e9978a08253f83de7611bd2" + react-deep-force-update@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.0.1.tgz#4f7f6c12c3e7de42f345992a3c518236fa1ecad3"