DavidMarquezF commented on issue #13839:
URL: https://github.com/apache/echarts/issues/13839#issuecomment-1319601929
In my project I build the config dynamically so I don't have a single config
for all available right now. However, the only important part you need is what
i posted (the xAxis). The rest should be quite easy to lay down.
I actually improved the design a bit more so that the labels from the second
groups are offset enough so that they don't overlap with the first row of
categories. I will share my code but it's not copy paste material, you will
need to figure it out a bit.
```typescript
let groupCategrories: { caption: string, length: number }[] = // Here you
should put the ordered list of the second level of categories. Caption is the
name it should have and length is how many subcategories it holds;
const labels: (string | number)[] = //Here put the list of labels from the
first row of labels
const longestLabel: string = labels.reduce<string>((a: string, b): string
=> {
const strB = b?.toString();
return a.length > strB?.length ? a : strB;
}, "") ?? "";
// We want to calculate the longest label in order to offset the second row
of labels
const maxPixelLengthStr = getTextWidth(longestLabel, DEFAULT_FONT);
const dummySeparator = "***";
const xAxis: XAXisOption [] = [{
name: this.xLabel,
nameLocation: "middle",
type: "category",
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
interval: 0,
rotate: 90,
},
splitArea: {
show: false
},
},
{
type: "category",
position: "bottom",
axisLine: {
show: false,
onZero: false
},
axisLabel: {
inside: true,
interval: (index, value) => {
return value !== "" && value !== dummySeparator;
},
},
offset: maxPixelLengthStr + 20,
axisTick: {
length: maxPixelLengthStr + 15,
lineStyle: {
color: "#CCC"
},
inside: true,
interval: (index, value) => {
return value === dummySeparator ||
(value !== "" && groupCategrories.find(c => c.caption ===
value).length <= 2);
}
},
splitArea: {
show: true,
interval: (index, value) => {
return value === dummySeparator;
}
},
data: groupCategrories.flatMap(c => {
const spaces: string[] = new Array<string>(c.length).fill("");
spaces[0] = dummySeparator;
spaces[Math.max(0, Math.trunc((spaces.length - 1) / 2))] =
c.caption;
return spaces;
})
}
];
//The getTextWidth helper function
function getTextWidth(text, font): number {
// re-use canvas object for better performance
const canvas = (getTextWidth as any).canvas || ((getTextWidth as
any).canvas = document.createElement("canvas"));
const context = canvas.getContext("2d");
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
const DEFAULT_FONT = "400 14px \"Inter var\", ui-sans-serif, system-ui,
-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\",
Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\",
\"Segoe UI Symbol\", \"Noto Color Emoji\"";
```
Then, for the rest of the config, just build a normal bar chart with a
single series. You just use a single series and then the axis config is
actually what does all of the work.
I'm sorry I can't share a full copy-paste example, I just don't have the
time to do that right now. However, with this info it should be quite straight
forward since the only complicated part about this is the xAxis itself and in
the snippet I've shared that should work right of the bat.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]