<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
  axisBottom,
  axisLeft,
  axisRight,
  axisTop,
  scaleLinear,
  select,
} from 'd3';
import {
  assign,
  mean,
  reduce,
  trim,
} from 'lodash';

import {
  calcLabelPosition,
  calcAxisTranslate,
  CommonPropTypes,
  propsChanged,
  stateFromPropUpdates,
} from '../../../utils';

import styles from './axis.css';

export const AXIS_TYPES = {
  top: axisTop,
  right: axisRight,
  bottom: axisBottom,
  left: axisLeft,
};

/**
 * `import { Axis } from 'ihme-ui'`
 */
export default class Axis extends React.PureComponent {
  static concatStyle(style) {
    return trim(reduce(
      style,
      (accum, value, attr) =>
        `${accum} ${attr.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`,
      ''
    ));
  }

  constructor(props) {
    super(props);
    this.state = stateFromPropUpdates(Axis.propUpdates, {}, props, {});

    this.storeRef = this.storeRef.bind(this);
  }

  componentDidMount() {
    this.drawAxis();
  }

  componentWillReceiveProps(nextProps) {
    this.setState(stateFromPropUpdates(Axis.propUpdates, this.props, nextProps, {}));
  }

  componentDidUpdate() {
    this.drawAxis();
  }

  componentWillUnmount() {
    this._axisSelection.remove();
  }

  drawAxis() {
    const {
      className,
      orientation,
      rotateTickLabels,
      scale,
      style,
      tickArguments,
      ticks,
      tickFormat,
      tickSize,
      tickSizeInner,
      tickSizeOuter,
      tickPadding,
      tickValues,
    } = this.props;

    const {
      translate,
    } = this.state;

    if (!this._axisSelection) {
      throw new Error();
    }

    const axis = AXIS_TYPES[orientation](scale);

    if (ticks) axis.ticks(ticks);
    if (tickArguments) axis.tickArguments(tickArguments);
    if (tickFormat) axis.tickFormat(tickFormat);
    if (tickSize) axis.tickSize(tickSize);
    if (tickSizeInner) axis.tickSizeInner(tickSizeInner);
    if (tickSizeOuter) axis.tickSizeOuter(tickSizeOuter);
    if (tickPadding) axis.tickPadding(tickPadding);
    if (tickValues) axis.tickValues(tickValues);

    this._axisSelection
      .attr('class', classNames(styles.common, className))
      .attr('transform', `translate(${translate.x}, ${translate.y})`)
      .attr('style', Axis.concatStyle(style))
      .call(axis);

    if (orientation === 'bottom') {
      // eslint-disable-next-line no-unused-expressions
      rotateTickLabels
        ? this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'end')
          .attr('dx', '-.8em')
          .attr('dy', '.15em')
          .attr('transform', 'rotate(-45)')
        : this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'middle')
          .attr('dx', '0')
          .attr('dy', '0.71em')
          .attr('transform', 'rotate(0)');
    } else if (orientation === 'top') {
      // eslint-disable-next-line no-unused-expressions
      rotateTickLabels
        ? this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'end')
          .attr('dx', '-.8em')
          .attr('dy', '0.29em')
          .attr('transform', 'rotate(45)')
        : this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'middle')
          .attr('dx', '0')
          .attr('dy', '0')<commit_msg>Modify dy & dx offsets for top/bottom axis tick labels such that they render with similar distances from their respective ticks. Use leading zeros.<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
  axisBottom,
  axisLeft,
  axisRight,
  axisTop,
  scaleLinear,
  select,
} from 'd3';
import {
  assign,
  mean,
  reduce,
  trim,
} from 'lodash';

import {
  calcLabelPosition,
  calcAxisTranslate,
  CommonPropTypes,
  propsChanged,
  stateFromPropUpdates,
} from '../../../utils';

import styles from './axis.css';

export const AXIS_TYPES = {
  top: axisTop,
  right: axisRight,
  bottom: axisBottom,
  left: axisLeft,
};

/**
 * `import { Axis } from 'ihme-ui'`
 */
export default class Axis extends React.PureComponent {
  static concatStyle(style) {
    return trim(reduce(
      style,
      (accum, value, attr) =>
        `${accum} ${attr.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`,
      ''
    ));
  }

  constructor(props) {
    super(props);
    this.state = stateFromPropUpdates(Axis.propUpdates, {}, props, {});

    this.storeRef = this.storeRef.bind(this);
  }

  componentDidMount() {
    this.drawAxis();
  }

  componentWillReceiveProps(nextProps) {
    this.setState(stateFromPropUpdates(Axis.propUpdates, this.props, nextProps, {}));
  }

  componentDidUpdate() {
    this.drawAxis();
  }

  componentWillUnmount() {
    this._axisSelection.remove();
  }

  drawAxis() {
    const {
      className,
      orientation,
      rotateTickLabels,
      scale,
      style,
      tickArguments,
      ticks,
      tickFormat,
      tickSize,
      tickSizeInner,
      tickSizeOuter,
      tickPadding,
      tickValues,
    } = this.props;

    const {
      translate,
    } = this.state;

    if (!this._axisSelection) {
      throw new Error();
    }

    const axis = AXIS_TYPES[orientation](scale);

    if (ticks) axis.ticks(ticks);
    if (tickArguments) axis.tickArguments(tickArguments);
    if (tickFormat) axis.tickFormat(tickFormat);
    if (tickSize) axis.tickSize(tickSize);
    if (tickSizeInner) axis.tickSizeInner(tickSizeInner);
    if (tickSizeOuter) axis.tickSizeOuter(tickSizeOuter);
    if (tickPadding) axis.tickPadding(tickPadding);
    if (tickValues) axis.tickValues(tickValues);

    this._axisSelection
      .attr('class', classNames(styles.common, className))
      .attr('transform', `translate(${translate.x}, ${translate.y})`)
      .attr('style', Axis.concatStyle(style))
      .call(axis);

    if (orientation === 'bottom') {
      // eslint-disable-next-line no-unused-expressions
      rotateTickLabels
        ? this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'end')
          .attr('dx', '-0.8em')
          .attr('dy', '0.15em')
          .attr('transform', 'rotate(-45)')
        : this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'middle')
          .attr('dx', '0')
          .attr('dy', '0.71em')
          .attr('transform', 'rotate(0)');
    } else if (orientation === 'top') {
      // eslint-disable-next-line no-unused-expressions
      rotateTickLabels
        ? this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'end')
          .attr('dx', '-0.65em')
          .attr('dy', '0.45em')
          .attr('transform', 'rotate(45)')
        : this._axisSelection
          .selectAll('text')
          .style('text-anchor', 'middle')
          .attr('dx', '0')
          .attr('dy', '0')
{'fraction_non_alphanumeric': 0.15511265164644714, 'fraction_numerical': 0.006354708261120739, 'mean_word_length': 2.6389910667367316, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7524403', 'n_tokens_mistral': 2246, 'n_tokens_neox': 2205, 'n_words': 425}