infect-frontend
Version:
infect fronend
117 lines (100 loc) • 4.32 kB
JSX
import React from 'react';
import resistanceTypes from '../../models/resistances/resistanceTypes';
import debug from 'debug';
import { observer } from 'mobx-react';
import { computed } from 'mobx';
import { supportsDominantBaseline } from '../../helpers/svgPolyfill';
import getVisibilityClassModifier from '../../helpers/getVisibilityClassModifier';
const log = debug('infect:ResistanceComponent');
class Resistance extends React.Component {
constructor() {
super();
// On init, resistances are always visible
this._wasVisible = true;
}
_getPreviousPosition() {
return `translate(${ (this._previousPosition && this._previousPosition.left) || 0},
${ (this._previousPosition && this._previousPosition.top) || 0})`;
}
get transformation() {
const xPos = this.props.resistance.xPosition;
const yPos = this.props.resistance.yPosition;
if (!xPos || !yPos) return this._getPreviousPosition();
// Center is always the middle of a regular (defaultRadius) circle
const left = xPos.left + this.props.matrix.defaultRadius;
const top = yPos.top + this.props.matrix.defaultRadius;
// Store previous position: If resistance is hidden, it should just stay where
// it is to not do unnecessary translations.
this._previousPosition = { left: left, top: top };
log('Resistance %o is placed at %d/%d', this, left, top);
// IE11 does not know style: transform – use the transform attribute
return `translate(${ left }, ${ top })`;
}
/**
* Return value that will be displayed in the resistance's circle.
* If import precision is given, use number, else use H/L/I.
*/
get value() {
const bestValue = this.props.resistance.mostPreciseValue;
if (bestValue.type.identifier === resistanceTypes.class.identifier ||
bestValue.type.identifier === resistanceTypes.default.identifier) {
return bestValue.value < 1/3 ? 'L' : (bestValue.value < 2/3 ? 'I' : 'H');
}
// If bestValue is 1, return 1, else .xx (without leading 0)
return bestValue.value === 1 ? 1 : (bestValue.value.toFixed(2) + '').substr(1);
}
/**
* Returns modifier for visibility class which determines the transitions.
*/
get classModifier() {
const visible = this.props.resistance.visible;
// We must also be watching transitions: If not, we only watch visible – which stays the
// same when modifier should change from -was-hidden-is-visible to -was-visible-is-visible
// and therefore won't call an update.
this.transformation;
const modifier = getVisibilityClassModifier(visible, this._wasVisible);
this._wasVisible = visible;
return modifier;
}
/**
* Bullets with sampleSize < 20 have opacity 0.5. See
*/
get opacity() {
return this.props.resistance.matchesOffsets ? 1 : 0.2;
}
_handleMouseEnter = () => {
this.props.matrix.setActiveResistance(this.props.resistance);
}
_handleMouseLeave = () => {
this.props.matrix.setActiveResistance(undefined);
}
render() {
return(
// Radius: sample size
// Color: Resistance (for given population filters)
<g transform={ this.transformation }
className={ 'resistanceMatrix__resistance js-resistance ' + this.classModifier }
data-antibiotic={ this.props.resistance.resistance.antibiotic.name }
data-bacterium={ this.props.resistance.resistance.bacterium.name }
onMouseEnter={ this._handleMouseEnter} onMouseLeave={this._handleMouseLeave }>
{ /* use <g> for content to give it an opacity depending on smapleSize. We cannot set
opacity on parent g as this would overwrite the filters (opacity 0 if not visible) */ }
<g style={ { opacity: this.opacity } }>
{/* circle: center is at 0/0, therefore move by radius/radius */}
<circle r={ this.props.resistance.radius } fill={ this.props.resistance.backgroundColor }
className="resistanceMatrix__resistanceCircle">
</circle>
{ /* dy -2: Adobe's font is not correctly middled, adjust by 2 px */ }
{ /* Don't display number if N < 20 */ }
<text textAnchor="middle" fill={ this.props.resistance.fontColor }
dominantBaseline="central" className="resistanceMatrix__resistanceText"
dy={ supportsDominantBaseline('-2', '0.35em') }>
{ Math.round((1 - this.value) * 100) }
</text>
</g>
</g>
);
}
}
export default Resistance;