Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions src/components/fields/AxisInterval.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const MILLISECONDS_IN_DAY = MILLISECONDS_IN_MINUTE * 60 * 24; // eslint-disable-
const DAYS_IN_MONTH = 30;
const MONTHS_IN_YEAR = 12; //eslint-disable-line

function twoDecimalsRound(value) {
return Math.round(value * 100) / 100;
}

function getSmallestUnit(milliseconds) {
const units = {
seconds: MILLISECONDS_IN_SECOND,
Expand All @@ -36,7 +40,7 @@ function getSmallestUnit(milliseconds) {
return smallestUnit;
}

class UnconnectedAxisInterval extends Component {
export class UnconnectedAxisInterval extends Component {
constructor(props) {
super(props);

Expand All @@ -54,13 +58,22 @@ class UnconnectedAxisInterval extends Component {

update(value) {
let adjustedValue = value < 0 ? 0 : value;
const isValueInteger = adjustedValue % 1 === 0;

if (this.state.units === 'years') {
adjustedValue = 'M' + adjustedValue * MONTHS_IN_YEAR;
if (isValueInteger) {
adjustedValue = 'M' + adjustedValue * MONTHS_IN_YEAR;
} else {
adjustedValue = adjustedValue * MONTHS_IN_YEAR * DAYS_IN_MONTH * MILLISECONDS_IN_DAY;
}
}

if (this.state.units === 'months') {
adjustedValue = 'M' + adjustedValue;
if (isValueInteger) {
adjustedValue = 'M' + adjustedValue;
} else {
adjustedValue = adjustedValue * DAYS_IN_MONTH * MILLISECONDS_IN_DAY;
}
}

if (this.state.units === 'days') {
Expand Down Expand Up @@ -89,7 +102,12 @@ class UnconnectedAxisInterval extends Component {
this.setState({units: value});

if (['years', 'months'].includes(value)) {
this.props.updatePlot('M' + Math.round(milliseconds / MILLISECONDS_IN_DAY / DAYS_IN_MONTH));
const nbMonths = milliseconds / MILLISECONDS_IN_DAY / DAYS_IN_MONTH;
if (nbMonths % 1 === 0) {
this.props.updatePlot('M' + nbMonths);
} else {
this.props.updatePlot(milliseconds);
}
} else {
this.props.updatePlot(milliseconds);
}
Expand All @@ -100,19 +118,25 @@ class UnconnectedAxisInterval extends Component {
typeof value === 'string' && value[0] === 'M' ? parseInt(value.substring(1), 10) : value;

if (this.state.units === 'years') {
return numericValue / MONTHS_IN_YEAR;
if (typeof value === 'string') {
return twoDecimalsRound(numericValue / MONTHS_IN_YEAR);
}
return twoDecimalsRound(numericValue / MILLISECONDS_IN_DAY / DAYS_IN_MONTH / MONTHS_IN_YEAR);
}
if (this.state.units === 'months') {
return numericValue;
if (typeof value === 'string') {
return twoDecimalsRound(numericValue);
}
return twoDecimalsRound(numericValue / MILLISECONDS_IN_DAY / DAYS_IN_MONTH);
}
if (this.state.units === 'days') {
return Math.round(numericValue / MILLISECONDS_IN_DAY);
return twoDecimalsRound(numericValue / MILLISECONDS_IN_DAY);
}
if (this.state.units === 'minutes') {
return Math.round(numericValue / MILLISECONDS_IN_MINUTE);
return twoDecimalsRound(numericValue / MILLISECONDS_IN_MINUTE);
}
if (this.state.units === 'seconds') {
return Math.round(numericValue / MILLISECONDS_IN_SECOND);
return twoDecimalsRound(numericValue / MILLISECONDS_IN_SECOND);
}
if (this.state.units === 'milliseconds') {
return numericValue;
Expand All @@ -126,8 +150,12 @@ class UnconnectedAxisInterval extends Component {
const binStartValue = this.props.fullContainer[attrHead].start;
const BinStartIsDate =
typeof binStartValue === 'string' && (isDateTime(binStartValue) || isJSDate(binStartValue));
const tick0 =
this.props.fullContainer.tick0 &&
(this.props.fullContainer.tick0 || this.props.fullContainer.colorbar.tick0);
const tick0IsDate = tick0 && (isDateTime(tick0) || isJSDate(tick0));

return BinStartIsDate ? (
return BinStartIsDate || tick0IsDate ? (
<Field {...this.props}>
<Dropdown
options={[
Expand All @@ -142,7 +170,7 @@ class UnconnectedAxisInterval extends Component {
onChange={value => this.onUnitChange(value)}
value={this.state.units}
/>
<div style={{height: '7px', width: '100%', display: 'block'}}> </div>
<div style={{width: '100%', display: 'block'}}> </div>
<NumericInput
value={this.getDisplayValue(this.props.fullValue)}
onUpdate={value => this.update(value)}
Expand Down
19 changes: 19 additions & 0 deletions src/components/fields/derived.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {UnconnectedNumeric} from './Numeric';
import {UnconnectedNumericOrDate} from './NumericOrDate';
import {UnconnectedAxisRangeValue} from './AxisRangeValue';
import {UnconnectedRadio} from './Radio';
import {UnconnectedAxisInterval} from './AxisInterval';
import Info from './Info';
import {UnconnectedColorPicker} from './ColorPicker';
import {UnconnectedTextEditor} from './TextEditor';
Expand Down Expand Up @@ -226,6 +227,24 @@ export const DTicks = connectToContainer(UnconnectedAxisRangeValue, {
},
});

export const DTicksInterval = connectToContainer(UnconnectedAxisInterval, {
modifyPlotProps: (props, context, plotProps) => {
const {fullContainer} = plotProps;
if (
fullContainer &&
fullContainer._name &&
(fullContainer._name.startsWith('lat') || fullContainer._name.startsWith('lon'))
) {
// don't mess with visibility on geo axes
return plotProps;
}
if (plotProps.isVisible && fullContainer && fullContainer.tickmode !== 'linear') {
plotProps.isVisible = false;
}
return plotProps;
},
});

class UnconnectedNumericFraction extends UnconnectedNumeric {}
UnconnectedNumericFraction.propTypes = UnconnectedNumeric.propTypes;
UnconnectedNumericFraction.defaultProps = {
Expand Down
2 changes: 2 additions & 0 deletions src/components/fields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
AxesRange,
NTicks,
DTicks,
DTicksInterval,
AxisAnchorDropdown,
ContourNumeric,
FillDropdown,
Expand Down Expand Up @@ -72,6 +73,7 @@ export {
AxesRange,
NTicks,
DTicks,
DTicksInterval,
AxesSelector,
ColorPicker,
ColorscalePicker,
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
AxesRange,
NTicks,
DTicks,
DTicksInterval,
AxesSelector,
ColorPicker,
ColorscalePicker,
Expand Down Expand Up @@ -103,6 +104,7 @@ export {
AxisSide,
NTicks,
DTicks,
DTicksInterval,
ShapeAccordion,
RangeSelectorAccordion,
SliderAccordion,
Expand Down
7 changes: 4 additions & 3 deletions src/default_panels/StyleAxesPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import {
AxesRange,
DTicks,
DTicksInterval,
NTicks,
ColorPicker,
Dropdown,
Expand Down Expand Up @@ -121,7 +122,7 @@ class StyleAxesPanel extends Component {
/>

<DTicks label={_('Step Offset')} attr="tick0" />
<DTicks label={_('Step Size')} attr="dtick" />
<DTicksInterval label={_('Step Size')} attr="dtick" />
<NTicks label={_('Max Number of Lines')} attr="nticks" />
</VisibilitySelect>
</PlotlySection>
Expand Down Expand Up @@ -274,7 +275,7 @@ class StyleAxesPanel extends Component {
/>

<DTicks label={_('Step Offset')} attr="tick0" />
<DTicks label={_('Step Size')} attr="dtick" />
<DTicksInterval label={_('Step Size')} attr="dtick" />
<NTicks label={_('Max Number of Labels')} attr="nticks" />
</VisibilitySelect>
</PlotlySection>
Expand Down Expand Up @@ -310,7 +311,7 @@ class StyleAxesPanel extends Component {
/>

<DTicks label={_('Step Offset')} attr="tick0" />
<DTicks label={_('Step Size')} attr="dtick" />
<DTicksInterval label={_('Step Size')} attr="dtick" />
<NTicks label={_('Max Number of Markers')} attr="nticks" />
</VisibilitySelect>
</PlotlySection>
Expand Down
5 changes: 3 additions & 2 deletions src/default_panels/StyleColorbarsPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ColorPicker,
VisibilitySelect,
NumericOrDate,
AxisInterval,
} from '../components';

export const traceHasColorbar = (trace, fullTrace) =>
Expand Down Expand Up @@ -213,7 +214,7 @@ const StyleColorBarsPanel = (props, {localize: _}) => {
/>

<NumericOrDate label={_('Step Offset')} attr={prefix + 'colorbar.tick0'} />
<Numeric label={_('Step Size')} attr={prefix + 'colorbar.dtick'} />
<AxisInterval label={_('Step Size')} attr={prefix + 'colorbar.dtick'} />
<Numeric label={_('Max Number of Labels')} attr={prefix + 'colorbar.nticks'} />
</VisibilitySelect>
</PlotlyFold>
Expand Down Expand Up @@ -241,7 +242,7 @@ const StyleColorBarsPanel = (props, {localize: _}) => {
/>

<NumericOrDate label={_('Step Offset')} attr={prefix + 'colorbar.tick0'} />
<Numeric label={_('Step Size')} attr={prefix + 'colorbar.dtick'} />
<AxisInterval label={_('Step Size')} attr={prefix + 'colorbar.dtick'} />
<Numeric label={_('Max Number of Labels')} attr={prefix + 'colorbar.nticks'} />
</VisibilitySelect>
</PlotlyFold>
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
TransformAccordion,
NTicks,
DTicks,
DTicksInterval,
AxesSelector,
PanelMessage,
Button,
Expand Down Expand Up @@ -107,6 +108,7 @@ export {
AxesRange,
NTicks,
DTicks,
DTicksInterval,
AxesSelector,
Button,
ColorPicker,
Expand Down