Safor
Safor

Reputation: 130

How to customize highlighted data point circles in Flex charts?

I need to customize a look and feel of standard Flex LineChart with LineSeries. I cannot figure out how to change default circles drawn when the mouse pointer is over a data point.

How to change UI element pointed by the red arrow?

Upvotes: 1

Views: 1374

Answers (3)

prismaticorb
prismaticorb

Reputation: 905

Timofei Davydik gave a very good answer, and it helped my work with datatips also

However I see in the comments that there was some confusion about how exactly to work with overriding the two massive functions, ChartBase.positionDataTips and ChartBase.positionAllDataTips.

A way to do this would be to do the following:

  1. Create a new chart class that extends ChartBase or a child of that.
  2. Set the ChartBase style, showDataTipTargets, to false.
  3. Create a new Style, showCustomDataTipTargets, on your custom chart class.
  4. Override positionDataTips and positionAllDatatips

The new overridden functions should look something like this:

override protected function positionDataTips():void
{
  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 following code as a guide, it is
  // copied from the ChartBase.positionDataTips
  /*
  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();
  */

}

Upvotes: 1

Safor
Safor

Reputation: 130

Solution

It is necessary to create a custom itemRenderer and draw whatever you want in the MOUSE_OVER event handler. Chart's showDataTipTargets property has to be set to false

While looking for a solution, I forgot that itemRenderer is the Flex component and can handle mouse events. My colleagues pointed to it and helped resolve the issue.

Code

CustomDataTipTargetRenderer.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                creationComplete="init()"
                ...>
    <fx:Script>
        <![CDATA[
            private function init():void
            {
                addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); 
                addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
            }

            private function onMouseOver(event:MouseEvent):void
            { 
                // Show custom data tip target point. 
            } 

            private function onMouseOut(event:MouseEvent):void
            { 
                // Hide custom data tip target point.
            }
        ]]>
    </fx:Script>
</s:ItemRenderer>

YourView.mxml

<mx:LineChart ...
              showDataTips="true"
              showDataTipTargets="false">
    ...
    <mx:series>
        <mx:LineSeries ... itemRenderer="yournamespace.CustomDataTipTargetRenderer">
            ...
        </mx:LineSeries>
    </mx:series>
</mx:LineChart>

Upvotes: 0

Timofei Davydik
Timofei Davydik

Reputation: 7294

If you want to remove those circles, set property showDataTipTargets of chart to false. If you want to customize them, you can:

  1. Create your custom dataTipRenderer and perform skinning and drawing there.
    OR
  2. Extend your LineChart and override positionAllDataTips method, which is defined in ChartBase class. Here's the code, responsible for drawing the circles:

Code:

if (showTarget) {

    if (len>1) {
        if (calloutStroke) {
            calloutStroke.apply(g, null, null);
            if (tipData.isRight) {
                g.moveTo(localPts.x,
                    localPts.y+tipData.height/2);
            g.lineTo(tipData.x,
                    localPts.y+tipData.height/2);
            g.lineTo(tipData.x, tipData.y);
        }
        else {
            if (layoutDirection == LayoutDirection.RTL) {
                g.moveTo(localPts.x-tipData.width,
                        localPts.y+tipData.height/2);
            }
            else {
                g.moveTo(localPts.x+tipData.width,
                        localPts.y+tipData.height/2);
            }
            g.lineTo(tipData.x,
                    localPts.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();

Upvotes: 1

Related Questions