Commit cf2e70dc authored by isstuev's avatar isstuev

x axis format

parent d2368c18
...@@ -130,7 +130,7 @@ const EthereumChart = () => { ...@@ -130,7 +130,7 @@ const EthereumChart = () => {
type="left" type="left"
scale={ yScale } scale={ yScale }
ticks={ 5 } ticks={ 5 }
tickFormat={ yTickFormat } tickFormatGenerator={ yTickFormat }
disableAnimation disableAnimation
/> />
<ChartOverlay ref={ overlayRef } width={ innerWidth } height={ innerHeight }> <ChartOverlay ref={ overlayRef } width={ innerWidth } height={ innerHeight }>
......
...@@ -7,11 +7,11 @@ interface Props extends Omit<React.SVGProps<SVGGElement>, 'scale'> { ...@@ -7,11 +7,11 @@ interface Props extends Omit<React.SVGProps<SVGGElement>, 'scale'> {
scale: d3.ScaleTime<number, number> | d3.ScaleLinear<number, number>; scale: d3.ScaleTime<number, number> | d3.ScaleLinear<number, number>;
disableAnimation?: boolean; disableAnimation?: boolean;
ticks: number; ticks: number;
tickFormat?: (domainValue: d3.AxisDomain, index: number) => string; tickFormatGenerator?: (axis: d3.Axis<d3.NumberValue>) => (domainValue: d3.AxisDomain, index: number) => string;
anchorEl?: SVGRectElement | null; anchorEl?: SVGRectElement | null;
} }
const ChartAxis = ({ type, scale, ticks, tickFormat, disableAnimation, anchorEl, ...props }: Props) => { const ChartAxis = ({ type, scale, ticks, tickFormatGenerator, disableAnimation, anchorEl, ...props }: Props) => {
const ref = React.useRef<SVGGElement>(null); const ref = React.useRef<SVGGElement>(null);
const textColorToken = useColorModeValue('blackAlpha.600', 'whiteAlpha.500'); const textColorToken = useColorModeValue('blackAlpha.600', 'whiteAlpha.500');
...@@ -23,10 +23,14 @@ const ChartAxis = ({ type, scale, ticks, tickFormat, disableAnimation, anchorEl, ...@@ -23,10 +23,14 @@ const ChartAxis = ({ type, scale, ticks, tickFormat, disableAnimation, anchorEl,
} }
const axisGenerator = type === 'left' ? d3.axisLeft : d3.axisBottom; const axisGenerator = type === 'left' ? d3.axisLeft : d3.axisBottom;
const axis = tickFormat ? const axis = axisGenerator(scale).ticks(ticks);
axisGenerator(scale).ticks(ticks).tickFormat(tickFormat) :
axisGenerator(scale).ticks(ticks); if (tickFormatGenerator) {
axis.tickFormat(tickFormatGenerator(axis));
}
const axisGroup = d3.select(ref.current); const axisGroup = d3.select(ref.current);
if (disableAnimation) { if (disableAnimation) {
axisGroup.call(axis); axisGroup.call(axis);
} else { } else {
...@@ -38,7 +42,7 @@ const ChartAxis = ({ type, scale, ticks, tickFormat, disableAnimation, anchorEl, ...@@ -38,7 +42,7 @@ const ChartAxis = ({ type, scale, ticks, tickFormat, disableAnimation, anchorEl,
.attr('opacity', 1) .attr('opacity', 1)
.attr('color', textColor) .attr('color', textColor)
.attr('font-size', '0.75rem'); .attr('font-size', '0.75rem');
}, [ scale, ticks, tickFormat, disableAnimation, type, textColor ]); }, [ scale, ticks, tickFormatGenerator, disableAnimation, type, textColor ]);
React.useEffect(() => { React.useEffect(() => {
if (!anchorEl) { if (!anchorEl) {
......
...@@ -55,7 +55,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title ...@@ -55,7 +55,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title
}, [ isGroupedValues, rangedItems ]); }, [ isGroupedValues, rangedItems ]);
const chartData = [ { items: displayedData, name: 'Value', color } ]; const chartData = [ { items: displayedData, name: 'Value', color } ];
const { yTickFormat, xScale, yScale } = useTimeChartController({ const { xTickFormat, yTickFormat, xScale, yScale } = useTimeChartController({
data: [ { items: displayedData, name: title, color } ], data: [ { items: displayedData, name: title, color } ],
width: innerWidth, width: innerWidth,
height: innerHeight, height: innerHeight,
...@@ -105,7 +105,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title ...@@ -105,7 +105,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title
type="left" type="left"
scale={ yScale } scale={ yScale }
ticks={ isEnlarged ? 6 : 3 } ticks={ isEnlarged ? 6 : 3 }
tickFormat={ yTickFormat } tickFormatGenerator={ yTickFormat }
disableAnimation disableAnimation
/> />
...@@ -115,6 +115,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title ...@@ -115,6 +115,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title
transform={ `translate(0, ${ innerHeight })` } transform={ `translate(0, ${ innerHeight })` }
ticks={ isMobile ? 1 : 4 } ticks={ isMobile ? 1 : 4 }
anchorEl={ overlayRef.current } anchorEl={ overlayRef.current }
tickFormatGenerator={ xTickFormat }
disableAnimation disableAnimation
/> />
......
...@@ -29,7 +29,8 @@ export default function useTimeChartController({ data, width, height }: Props) { ...@@ -29,7 +29,8 @@ export default function useTimeChartController({ data, width, height }: Props) {
); );
const yMin = useMemo( const yMin = useMemo(
() => d3.min(data, ({ items }) => d3.min(items, ({ value }) => value)) || 0, // use -1 instead of 0 to correctly display the curve between two zero points.
() => d3.min(data, ({ items }) => d3.min(items, ({ value }) => value)) || -1,
[ data ], [ data ],
); );
...@@ -51,8 +52,27 @@ export default function useTimeChartController({ data, width, height }: Props) { ...@@ -51,8 +52,27 @@ export default function useTimeChartController({ data, width, height }: Props) {
[ height, yMin, yMax ], [ height, yMin, yMax ],
); );
const xTickFormat = (d: d3.AxisDomain) => d.toLocaleString(); const xTickFormat = (axis: d3.Axis<d3.NumberValue>) => (d: d3.AxisDomain) => {
const yTickFormat = (d: d3.AxisDomain) => formatNumberToMetricPrefix(Number(d)); let format: (date: Date) => string;
const scale = axis.scale();
const extent = scale.domain();
const span = Number(extent[1]) - Number(extent[0]);
if (span > 365 * 24 * 60 * 60 * 1000) {
format = d3.timeFormat('%Y');
} else if (span > 30 * 24 * 60 * 60 * 1000) {
format = d3.timeFormat('%b');
} else if (span > 7 * 24 * 60 * 60 * 1000) {
format = d3.timeFormat('%b %d');
} else {
format = d3.timeFormat('%a %d');
}
return format(d as Date);
};
const yTickFormat = () => (d: d3.AxisDomain) => formatNumberToMetricPrefix(Number(d));
return { return {
xTickFormat, xTickFormat,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment