| 1 | import * as d3Scales from 'victory-vendor/d3-scale';
|
|---|
| 2 | import { upperFirst } from '../DataUtils';
|
|---|
| 3 |
|
|---|
| 4 | /**
|
|---|
| 5 | * This is internal representation of scale used in Recharts.
|
|---|
| 6 | * Users will provide CustomScaleDefinition or a string, which we will parse into RechartsScale.
|
|---|
| 7 | * Most importantly, RechartsScale is fully immutable - there are no setters that mutate the scale in place.
|
|---|
| 8 | * This is important for React integration - if the scale changes, we want to trigger re-renders.
|
|---|
| 9 | * Mutating the scale in place would not trigger re-renders, leading to stale UI.
|
|---|
| 10 | */
|
|---|
| 11 |
|
|---|
| 12 | /**
|
|---|
| 13 | * Position within a band for banded scales.
|
|---|
| 14 | * In scales that are not banded, this parameter is ignored.
|
|---|
| 15 | *
|
|---|
| 16 | * @inline
|
|---|
| 17 | */
|
|---|
| 18 |
|
|---|
| 19 | function getD3ScaleFromType(realScaleType) {
|
|---|
| 20 | if (realScaleType in d3Scales) {
|
|---|
| 21 | // @ts-expect-error we should do better type verification here
|
|---|
| 22 | return d3Scales[realScaleType]();
|
|---|
| 23 | }
|
|---|
| 24 | var name = "scale".concat(upperFirst(realScaleType));
|
|---|
| 25 | if (name in d3Scales) {
|
|---|
| 26 | // @ts-expect-error we should do better type verification here
|
|---|
| 27 | return d3Scales[name]();
|
|---|
| 28 | }
|
|---|
| 29 | return undefined;
|
|---|
| 30 | }
|
|---|
| 31 | export function d3ScaleToRechartsScale(d3Scale) {
|
|---|
| 32 | var ticksFn = d3Scale.ticks;
|
|---|
| 33 | var bandwidthFn = d3Scale.bandwidth;
|
|---|
| 34 | var d3Range = d3Scale.range();
|
|---|
| 35 | var range = [Math.min(...d3Range), Math.max(...d3Range)];
|
|---|
| 36 | return {
|
|---|
| 37 | domain: () => d3Scale.domain(),
|
|---|
| 38 | range: function (_range) {
|
|---|
| 39 | function range() {
|
|---|
| 40 | return _range.apply(this, arguments);
|
|---|
| 41 | }
|
|---|
| 42 | range.toString = function () {
|
|---|
| 43 | return _range.toString();
|
|---|
| 44 | };
|
|---|
| 45 | return range;
|
|---|
| 46 | }(() => range),
|
|---|
| 47 | rangeMin: () => range[0],
|
|---|
| 48 | rangeMax: () => range[1],
|
|---|
| 49 | isInRange(value) {
|
|---|
| 50 | var first = range[0];
|
|---|
| 51 | var last = range[1];
|
|---|
| 52 | return first <= last ? value >= first && value <= last : value >= last && value <= first;
|
|---|
| 53 | },
|
|---|
| 54 | bandwidth: bandwidthFn ? () => bandwidthFn.call(d3Scale) : undefined,
|
|---|
| 55 | ticks: ticksFn ? count => ticksFn.call(d3Scale, count) : undefined,
|
|---|
| 56 | map: (input, options) => {
|
|---|
| 57 | var baseValue = d3Scale(input);
|
|---|
| 58 | if (baseValue == null) {
|
|---|
| 59 | return undefined;
|
|---|
| 60 | }
|
|---|
| 61 | if (d3Scale.bandwidth && options !== null && options !== void 0 && options.position) {
|
|---|
| 62 | var bandWidth = d3Scale.bandwidth();
|
|---|
| 63 | switch (options.position) {
|
|---|
| 64 | case 'middle':
|
|---|
| 65 | baseValue += bandWidth / 2;
|
|---|
| 66 | break;
|
|---|
| 67 | case 'end':
|
|---|
| 68 | baseValue += bandWidth;
|
|---|
| 69 | break;
|
|---|
| 70 | default:
|
|---|
| 71 | // 'start' requires no adjustment
|
|---|
| 72 | break;
|
|---|
| 73 | }
|
|---|
| 74 | }
|
|---|
| 75 | return baseValue;
|
|---|
| 76 | }
|
|---|
| 77 | };
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | /**
|
|---|
| 81 | * Converts external scale definition into internal RechartsScale definition.
|
|---|
| 82 | * @param scale custom function scale - if you have the string, use `combineRealScaleType` first
|
|---|
| 83 | * @param axisDomain
|
|---|
| 84 | * @param axisRange
|
|---|
| 85 | */
|
|---|
| 86 |
|
|---|
| 87 | export function rechartsScaleFactory(scale, axisDomain, axisRange) {
|
|---|
| 88 | if (typeof scale === 'function') {
|
|---|
| 89 | return d3ScaleToRechartsScale(scale.copy().domain(axisDomain).range(axisRange));
|
|---|
| 90 | }
|
|---|
| 91 | if (scale == null) {
|
|---|
| 92 | return undefined;
|
|---|
| 93 | }
|
|---|
| 94 | var d3ScaleFunction = getD3ScaleFromType(scale);
|
|---|
| 95 | if (d3ScaleFunction == null) {
|
|---|
| 96 | return undefined;
|
|---|
| 97 | }
|
|---|
| 98 | d3ScaleFunction.domain(axisDomain).range(axisRange);
|
|---|
| 99 | return d3ScaleToRechartsScale(d3ScaleFunction);
|
|---|
| 100 | } |
|---|