我花了很长时间处理这个问题以及与图表数据提示相关的其他问题。
我在similar question 有一个类似问题的答案,你可以看看。我将在此处发布该答案的修改版本,因为它从未被标记为问题的答案 :-(
没有任何好的文档说明如何准确地覆盖ChartBase.positionDataTips 和ChartBase.positionAllDataTips 这两个大型函数。我花了很多天时间研究 mx 图表代码以确定覆盖这些函数的最佳方法,以便让弹性图表符合我的意愿:-P
这是一些(来之不易的)代码,用于自定义数据提示目标,即鼠标悬停在系列上时显示的默认靶心圆。
- 创建一个扩展
ChartBase 或其子级的新图表类。
- 将
ChartBase 样式showDataTipTargets 设置为false。
- 在您的自定义图表类上创建一个新样式
showCustomDataTipTargets。
- 您甚至可能想为
dataTipTargetRenderer 创建一个样式来进行自定义渲染。这将是一个更优雅的解决方案。
- 覆盖
positionDataTips 和 positionAllDatatips
- 我已经编写了绘制正方形的代码,但要绘制更大的圆形,只需使用您自己的值代替
TOOLTIP_TARGET_RADIUS 和 TOOLTIP_TARGET_INNER_RADIUS。
新的覆盖函数如下所示:
override protected function positionDataTips():void
{
// Setting the showDataTipTargets to false will prevent
// super.positionDataTips() from drawing the default bulls-eyes.
// By setting this style, we allow super.positionDataTips() to do all
// the "heavy-lifting" involved with dataTip positioning and dataTip box rendering
// before we do our customization of the dataTipTargets
this.setStyle("showDataTipTargets", false);
// this will do all the normal rendering of the datatips and callout
// but it will not draw the dataTipTarget because that is dependent upon
// the style, showDataTipTargets
super.positionDataTips();
// now here you draw your custom datatip target.
// Use the code from ChartBase.positionDataTips as a guide,
// I have written code to simply draw a square instead of circle.
// You can do much more complex things here as needed.
if (len > 1)
{
// calloutStroke code is copied verbatim from super function
// However, you can customize the calloutStroke rendering just as easily
// by modifying the following code!
if (calloutStroke)
{
calloutStroke.apply(g,null,null);
if (tipData.isRight)
{
g.moveTo(chartLocalPts.x,
chartLocalPts.y + tipData.height / 2);
g.lineTo(tipData.x,
chartLocalPts.y + tipData.height / 2);
g.lineTo(tipData.x, tipData.y);
}
else
{
if(layoutDirection == LayoutDirection.RTL)
{
g.moveTo(chartLocalPts.x - tipData.width,
chartLocalPts.y + tipData.height / 2);
}
else
{
g.moveTo(chartLocalPts.x + tipData.width,
chartLocalPts.y + tipData.height / 2);
}
g.lineTo(tipData.x,
chartLocalPts.y + tipData.height / 2);
g.lineTo(tipData.x, tipData.y);
}
}
}
// Here is custom dataTipTarget code!!
// It draws a 5x5 square around the point on the series
var tipColor:uint = tipData.hd.contextColor;
g.lineStyle(1, tipColor, 100);
g.moveTo(tipData.x, tipData.y);
g.beginFill(0xFFFFFF, 1);
g.drawRect(tipData.x, tipData.y, 5, 5);
g.endFill();
}
以下是从ChartBase.positionDataTip()复制的代码供参考:
if (len > 1)
{
if (calloutStroke)
{
calloutStroke.apply(g,null,null);
if (tipData.isRight)
{
g.moveTo(chartLocalPts.x,
chartLocalPts.y + tipData.height / 2);
g.lineTo(tipData.x,
chartLocalPts.y + tipData.height / 2);
g.lineTo(tipData.x, tipData.y);
}
else
{
if(layoutDirection == LayoutDirection.RTL)
{
g.moveTo(chartLocalPts.x - tipData.width,
chartLocalPts.y + tipData.height / 2);
}
else
{
g.moveTo(chartLocalPts.x + tipData.width,
chartLocalPts.y + tipData.height / 2);
}
g.lineTo(tipData.x,
chartLocalPts.y + tipData.height / 2);
g.lineTo(tipData.x, tipData.y);
}
}
}
var tipColor:uint = tipData.hd.contextColor;
g.lineStyle(1, tipColor, 100);
g.moveTo(tipData.x, tipData.y);
g.beginFill(0xFFFFFF, 1);
g.drawCircle(tipData.x, tipData.y, TOOLTIP_TARGET_RADIUS);
g.endFill();
g.beginFill(tipColor, 1);
g.drawCircle(tipData.x, tipData.y,
TOOLTIP_TARGET_INNER_RADIUS);
g.endFill();