覆盖数据提示圆

时间:2012-01-31 17:17:46

标签: flex charts geometry datatip

在弹性图表中,您可以自定义显示数据提示信息的框,但是有没有简单的方法来更改数据提示框旁边显示的小圆圈?

http://help.adobe.com/en_US/flex/using/images/chd_SimpleDataTip.png

我在ChartBase中找到了方法positionDataTips(),它似乎可以绘制圆形图。我打算继承LineChart并使用我的修改版本覆盖该方法。但是,此方法需要访问许多只能由ChartBase访问的私有实例变量。

思想?

1 个答案:

答案 0 :(得分:4)

我花了很长时间处理这个以及与图表数据提示有关的其他问题。 我在similar question找到了一个类似问题的答案,你可以看一下。我将在这里发布该答案的修改版本,因为它从未被标记为问题的答案: - (


没有任何关于如何完全覆盖两个大型函数ChartBase.positionDataTipsChartBase.positionAllDataTips的文档。我花了很多天时间挖掘mx图表代码以确定覆盖这些函数的最佳方法,以便根据我的意愿弯曲flex图表:-P

以下是一些(来之不易的)代码,用于自定义数据提示目标,鼠标悬停在系列上时显示的默认牛眼圈。

  1. 创建一个扩展ChartBase或其子级的新图表类。
  2. ChartBase样式showDataTipTargets设置为false。
  3. 在自定义图表类上创建新样式showCustomDataTipTargets
    • 你甚至可能想为dataTipTargetRenderer创建一个样式来进行自定义渲染。这将是一个更优雅的解决方案。
  4. 覆盖positionDataTipspositionAllDatatips
    • 我已编写代码来绘制正方形,但为了制作更大的圆,只需使用您自己的值代替TOOLTIP_TARGET_RADIUSTOOLTIP_TARGET_INNER_RADIUS
  5. 新的重写函数看起来像这样:

    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();