那Ext.chart.axis.Axis#drawHoriztontalLabels
就是你需要覆盖。onPlaceLabel
是写在图表本身的东西。就像栏顶部的标签一样,你明白我的意思吗?
干净的方法是覆盖类并实现一些快乐的选项。如果您想了解实现,我会让您探索我在帖子末尾放置的完整代码......
Ext.define('Ext.ux.chart.axis.Axis.OverlappingLabelOptions', {
override: 'Ext.chart.axis.Axis'
,labelRows: 1
,hideOverlappingLabels: true
,drawHorizontalLabels: function() {
// ... see at the end of the post for the full implementation
}
});
使用 包含此覆盖类require
后,您可以在轴定义中使用这两个选项。例如:
{
type: 'Category',
position: 'bottom',
fields: ['name'],
title: 'Sample Metrics',
labelRows: 5,
hideOverlappingLabels: false
}
我的第一次尝试是自动将重叠标签向下推一排。这就是你通过设置获得的labelRows: 'auto'
。它在某些条件下运行良好,并且具有自动化的优势。
![在此处输入图像描述](https://i.stack.imgur.com/8CDum.jpg)
不幸的是,它会变得非常混乱:
![在此处输入图像描述](https://i.stack.imgur.com/6h8u0.jpg)
所以我求助于实现一个选项,让您固定标签行数,并在这些行之间均匀分布标签。我还添加了hideOverlappingLabels
确保即使我们错过运气并且某些标签结束重叠也不会丢失标签。
这是您使用此配置获得的结果:
{
// ...
hideOverlappingLabels: false,
labelRows: 5
}
![在此处输入图像描述](https://i.stack.imgur.com/crXQV.jpg)
我希望这会给你你所需要的,或者至少是让 Ext 的代码满足你的愿望的知识!
全面实施
/**
* This override adds a {@link #labelRows} option to draw horizontal axis labels on multiple
* rows, and also an {@link #hideOverlappingLabels} option.
*/
Ext.define('Ext.ux.chart.axis.Axis.OverlappingLabelOptions', {
override: 'Ext.chart.axis.Axis'
,alternateClassName: 'Ext.ux.AxisOverlappingLabelOptions'
/**
* @cfg {Integer/String}
*
* Number of label rows. If this option is set to 'auto', then overlapping labels will
* be drawn on the next row where they don't overlap. Which can give a messy result.
*/
,labelRows: 1
/**
* @cfg {Boolean}
*
* Set to false to prevent automatic hiding of overlapping labels.
*/
,hideOverlappingLabels: true
,drawHorizontalLabels: function() {
var me = this,
labelConf = me.label,
floor = Math.floor,
max = Math.max,
axes = me.chart.axes,
insetPadding = me.chart.insetPadding,
gutters = me.chart.maxGutters,
position = me.position,
inflections = me.inflections,
ln = inflections.length,
labels = me.labels,
maxHeight = 0,
ratio,
bbox, point, prevLabel, prevLabelId,
adjustEnd = me.adjustEnd,
hasLeft = axes.findIndex('position', 'left') != -1,
hasRight = axes.findIndex('position', 'right') != -1,
textLabel, text,
last, x, y, i, firstLabel;
var labelRows = Ext.num(this.labelRows, 1),
autoOffsetLabels = this.labelRows === 'auto',
hideLabels = this.hideOverlappingLabels;
var lastLabelOnRow = [],
row, j;
last = ln - 1;
//get a reference to the first text label dimensions
point = inflections[0];
firstLabel = me.getOrCreateLabel(0, me.label.renderer(labels[0]));
ratio = Math.floor(Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0)));
for (i = 0; i < ln; i++) {
row = 0; // rx: start at first row
point = inflections[i];
text = me.label.renderer(labels[i]);
textLabel = me.getOrCreateLabel(i, text);
bbox = textLabel._bbox;
//maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding);
x = floor(point[0] - (ratio ? bbox.height : bbox.width) / 2);
if (adjustEnd && gutters.left == 0 && gutters.right == 0) {
if (i == 0 && !hasLeft) {
x = point[0];
}
else if (i == last && !hasRight) {
x = Math.min(x, point[0] - bbox.width + insetPadding);
}
}
if (position == 'top') {
y = point[1] - (me.dashSize * 2) - me.label.padding - (bbox.height / 2);
}
else {
y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2);
}
// rx: vertical offset
y += (i % labelRows) * bbox.height;
textLabel.setAttributes({
hidden: false,
x: x,
y: y
}, true);
if (autoOffsetLabels) {
// rx: find the row on which we can draw the label without overlapping
for (j=0; j<lastLabelOnRow.length; j++) {
if (me.intersect(textLabel, lastLabelOnRow[j])) {
row++;
textLabel.setAttributes({
y: y + row * bbox.height
}, true);
}
}
// rx: calc maxHeight knowing the row
maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding + (bbox.height * row));
// rx: keep reference to know where we can place the next label
lastLabelOnRow[row] = textLabel;
} else {
if (hideLabels) {
// Skip label if there isn't available minimum space
if (i != 0 && (me.intersect(textLabel, prevLabel)
|| me.intersect(textLabel, firstLabel))) {
if (i === last && prevLabelId !== 0) {
prevLabel.hide(true);
} else {
textLabel.hide(true);
continue;
}
}
}
maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding + bbox.height * (i % labelRows));
}
prevLabel = textLabel;
prevLabelId = i;
}
return maxHeight;
}
});