-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathaxis-height-linear-dual.tsx
More file actions
106 lines (94 loc) · 3.42 KB
/
axis-height-linear-dual.tsx
File metadata and controls
106 lines (94 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { useState } from "react";
import { ComboLineColumnState } from "@/charts/combo/combo-line-column-state";
import { ComboLineDualState } from "@/charts/combo/combo-line-dual-state";
import {
TICK_PADDING,
useRenderAxisHeightLinear,
} from "@/charts/shared/axis-height-linear";
import { useChartState } from "@/charts/shared/chart-state";
import { useChartTheme } from "@/charts/shared/use-chart-theme";
import { OpenMetadataPanelWrapper } from "@/components/metadata-panel";
import { theme } from "@/themes/federal";
import { getTextHeight, getTextWidth } from "@/utils/get-text-width";
import { useAxisTitleAdjustments } from "@/utils/use-axis-title-adjustments";
import { TITLE_VPADDING } from "./combo-line-container";
const TITLE_HPADDING = 8;
const TOP_MARGIN = 4;
type AxisHeightLinearDualProps = {
orientation?: "left" | "right";
};
export const AxisHeightLinearDual = (props: AxisHeightLinearDualProps) => {
const { orientation = "left" } = props;
const leftAligned = orientation === "left";
const { gridColor, labelColor, axisLabelFontSize } = useChartTheme();
const [ref, setRef] = useState<SVGGElement | null>(null);
const { y, yOrientationScales, colors, bounds, maxRightTickWidth } =
useChartState() as ComboLineDualState | ComboLineColumnState;
const yScale = yOrientationScales[orientation];
const { margins } = bounds;
const axisTitle = y[orientation].label;
const axisTitleWidth =
getTextWidth(axisTitle, { fontSize: axisLabelFontSize }) + TICK_PADDING;
const color = colors(axisTitle);
const { isOverlapping, overlapAmount } = useAxisTitleAdjustments({
leftAxisTitle: y.left.label,
rightAxisTitle: y.right.label,
containerWidth: bounds.chartWidth,
fontSize: axisLabelFontSize,
});
useRenderAxisHeightLinear(ref, {
id: `axis-height-linear-${orientation}`,
orientation,
scale: yScale,
width: bounds.chartWidth,
height: bounds.chartHeight,
margins,
lineColor: gridColor,
textColor: labelColor,
});
const rightXAlignment =
bounds.chartWidth +
margins.left -
(isOverlapping ? axisTitleWidth / overlapAmount : axisTitleWidth) +
maxRightTickWidth +
TICK_PADDING -
TITLE_HPADDING * (isOverlapping ? Math.floor(overlapAmount) : 2);
const titleWidth = isOverlapping ? axisTitleWidth / overlapAmount : "auto";
const axisLabelHeight = getTextHeight(axisTitle, {
fontSize: axisLabelFontSize,
});
return (
<>
<foreignObject
x={leftAligned ? 0 : rightXAlignment}
width={axisTitleWidth + TITLE_HPADDING * 2}
height={
(isOverlapping
? axisLabelHeight * Math.ceil(overlapAmount) + TITLE_VPADDING
: axisLabelHeight + TITLE_VPADDING) *
2 +
TOP_MARGIN
}
color={theme.palette.getContrastText(color)}
style={{ display: "flex" }}
>
<OpenMetadataPanelWrapper component={y[orientation].dimension}>
<span
style={{
width: titleWidth,
fontSize: axisLabelFontSize,
backgroundColor: color,
color: theme.palette.getContrastText(color),
padding: `${TITLE_VPADDING}px ${TITLE_HPADDING}px`,
borderRadius: 4,
wordBreak: "break-word",
}}
>
{axisTitle}
</span>
</OpenMetadataPanelWrapper>
</foreignObject>
<g ref={(newRef) => setRef(newRef)} />
</>
);
};