Skip to content
This repository has been archived by the owner on Feb 19, 2022. It is now read-only.

Feature/pass mapped tick to tick format #471

Merged
merged 3 commits into from
May 24, 2017
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
1 change: 1 addition & 0 deletions src/components/victory-axis/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export default {
const y = isVertical ?
((props.height - vPadding) / 2) + padding.bottom + globalTransform.y :
(sign * labelPadding) + globalTransform.y;

return {
x,
y,
Expand Down
62 changes: 50 additions & 12 deletions src/components/victory-chart/helper-methods.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*eslint no-magic-numbers: ["error", { "ignore": [0, 1, 2] }]*/
import { invert, sortBy, values } from "lodash";
import { isFunction, flow, invert, sortBy, values } from "lodash";
import Axis from "../../helpers/axis";
import Wrapper from "../../helpers/wrapper";
import React from "react";
Expand Down Expand Up @@ -124,24 +124,62 @@ export default {
return this.getTicksFromAxis(...args) || this.getTicksFromData(...args);
},

getTickFormat(component, axis, calculatedProps) {
const currentAxis = Helpers.getCurrentAxis(axis, calculatedProps.horizontal);
const stringMap = calculatedProps.stringMap[currentAxis];
const tickValues = component.props.tickValues;
const useIdentity = tickValues && !Collection.containsStrings(tickValues) &&
!Collection.containsDates(tickValues);
if (useIdentity) {
return identity;
} else if (stringMap !== null) {
getArrayFormatter(tickValues, tickFormat) {
// For tickFormat lists, use the list in order
if (Array.isArray(tickFormat)) {
return (index) => () => tickFormat[index];
}

// For non-numerical tickValues lists, use the list in order
if (Array.isArray(tickValues) && !Collection.containsNumbers(tickValues)) {
return (index) => () => tickValues[index];
}

// identity
return () => (tick) => tick;
},

getFunctionFormatter(tickFormat) {
return isFunction(tickFormat) ? tickFormat : identity;
},

getStringMapFormatter(stringMap) {
// When string maps are present, convert tick to string
if (stringMap !== null) {
const tickValueArray = sortBy(values(stringMap), (n) => n);
const invertedStringMap = invert(stringMap);
const dataNames = tickValueArray.map((tick) => invertedStringMap[tick]);
// string ticks should have one tick of padding at the beginning
const dataTicks = ["", ...dataNames, ""];
return (x) => dataTicks[x];
} else {
return calculatedProps.scale[currentAxis].tickFormat() || identity;
}

return identity;
},

getScaleFormatter(stringMap, tickFormat, tickValues, calculatedProps, currentAxis) { // eslint-disable-line
if (stringMap || tickFormat || tickValues) {
return identity;
}

return calculatedProps.scale[currentAxis].tickFormat();
},

getTickFormat(component, axis, calculatedProps) {
const { tickFormat, tickValues } = component.props;
const currentAxis = Helpers.getCurrentAxis(axis, calculatedProps.horizontal);
const stringMap = calculatedProps.stringMap[currentAxis];

return (tick, index) => {
const tickFormatterPipeline = [
this.getScaleFormatter(stringMap, tickFormat, tickValues, calculatedProps, currentAxis),
this.getStringMapFormatter(stringMap),
this.getArrayFormatter(tickValues, tickFormat)(index),
this.getFunctionFormatter(tickFormat)
];

return flow(tickFormatterPipeline)(tick);
};
},

createStringMap(props, axis, childComponents) {
Expand Down
4 changes: 1 addition & 3 deletions src/components/victory-chart/victory-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ export default class VictoryChart extends React.Component {
const axis = child.type.getAxis(child.props);
const axisOffset = ChartHelpers.getAxisOffset(props, calculatedProps);
const tickValues = ChartHelpers.getTicks(calculatedProps, axis, child);
const tickFormat =
child.props.tickFormat || ChartHelpers.getTickFormat(child, axis, calculatedProps);
const tickFormat = ChartHelpers.getTickFormat(child, axis, calculatedProps);
const offsetY = axis === "y" ? undefined : axisOffset.y;
const offsetX = axis === "x" ? undefined : axisOffset.x;
const crossAxis = child.props.crossAxis === false ? false : true;
Expand All @@ -102,7 +101,6 @@ export default class VictoryChart extends React.Component {
crossAxis,
orientation
};

}

getChildProps(child, props, calculatedProps) {
Expand Down
68 changes: 60 additions & 8 deletions test/client/spec/components/victory-chart/helper-methods.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Helpers from "src/components/victory-chart/helper-methods";
import React from "react";
import { VictoryAxis, VictoryLine, VictoryBar } from "src/index";
import { Log, Data, Scale } from "victory-core";
import { Log, Data } from "victory-core";
import Wrapper from "src/helpers/wrapper";

describe("victory-chart/helpers-methods", () => {
Expand Down Expand Up @@ -158,30 +158,82 @@ describe("victory-chart/helpers-methods", () => {

describe("getTickFormat", () => {
const stringMap = { x: { "a": 1, "b": 2, "c": 3 } };
const scale = { x: Scale.getBaseScale({ scale: "linear" }, "x") };
const nullStringMap = { x: null };
const scale = { x: { tickFormat: () => () => "scaleFormatTick" } };

it("returns the identity function when tickValues are not strings", () => {
it("returns the identity function when tickValues are numerical", () => {
const props = { tickValues: [1, 2, 3] };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap, scale });
const val = { a: 3 };
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap: nullStringMap });
const val = 2;
expect(formatResult).to.be.a("function");
expect(formatResult(val)).to.equal(val);
});

it("returns a function from a string map", () => {
const victoryAxis = getVictoryAxis({});
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap, scale });
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(1)).to.equal("a");
});

it("returns the tickFormat function from scale", () => {
const victoryAxis = getVictoryAxis({});
const formatResult = Helpers.getTickFormat(
victoryAxis, "x", { stringMap: { x: null }, scale }
victoryAxis, "x", { stringMap: nullStringMap, scale }
);
expect(formatResult(1)).to.equal(scale.x.tickFormat()(1));
expect(formatResult(1)).to.equal("scaleFormatTick");
});

it("uses custom tickFormat", () => {
const props = { tickFormat: (tick) => tick + 1 };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap: nullStringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(1)).to.equal(2);
});

it("passes string map result to custom tickFormat prop", () => {
const props = { tickFormat: (tick) => `${tick} yo` };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(1)).to.equal("a yo");
});

it("uses string array tickValues for tick formatting", () => {
const props = { tickValues: ["orange", "banana", "apple"] };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap: nullStringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(5, 0)).to.equal("orange");
expect(formatResult(5, 2)).to.equal("apple");
});

it("uses string array tickFormat for tick formatting", () => {
const props = { tickFormat: ["orange", "banana", "apple"] };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap: nullStringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(5, 0)).to.equal("orange");
expect(formatResult(5, 2)).to.equal("apple");
});

it("uses tickFormat array over tickValues", () => {
const props = { tickValues: [1, 2, 3], tickFormat: ["orange", "banana", "apple"] };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap: nullStringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(5, 0)).to.equal("orange");
expect(formatResult(5, 2)).to.equal("apple");
});

it("runs tickFormat fn after tick values are applied", () => {
const props = { tickValues: ["a", "b", "c"], tickFormat: (tick) => `${tick} yo` };
const victoryAxis = getVictoryAxis(props);
const formatResult = Helpers.getTickFormat(victoryAxis, "x", { stringMap: nullStringMap });
expect(formatResult).to.be.a("function");
expect(formatResult(1, 1)).to.equal("b yo");
});
});

Expand Down