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.
3 Answers
If you want to remove those circles, set property showDataTipTargets
of chart to false
. If you want to customize them, you can:
- Create your custom
dataTipRenderer
and perform skinning and drawing there.
OR - Extend your
LineChart
and overridepositionAllDataTips
method, which is defined inChartBase
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();

- 7,244
- 7
- 33
- 59
-
1. you wrote: "set property showDataTipTargets of chart to false", but it is not what I need. The showDataTipTargets displays dots in the data points. The dot I pointed out appears when you move the cursor over one of data points. – Safor Oct 07 '11 at 11:29
-
2. "custom dataTipRenderer" does not allow me to draw the circle point I specified on the image above. I tried to duplicate the functionality of CircleItemRenderer class and compleately removed the funcationality responsible for drawing any elements - still I could see the circle with dot when I moved the mouse over. – Safor Oct 07 '11 at 11:30
-
3. "Extend your LineChart and override positionAllDataTips method, which is defined in ChartBase class" - only this one can help, but I have to figure out how to rewrite that giant positionAllDataTips method... – Safor Oct 07 '11 at 12:21
-
I gave up to override functionality of drawing different data points. The code above, provided by Timofei, is duplicated (!) in two places: ChartBase.positionDataTips and ChartBase.positionAllDataTips methods. Each method is about 350 lines of code and use some private variables initialized and populated in different places of the control! In order to override drawing of the circles, one has to almost duplicate about 1000 lines of code from the base control (( My conclusion is the ChartBase is awful for customization of such element. Anyway I thank Timofei for the help. – Safor Oct 07 '11 at 13:40
-
@timofei-davydik As Safor has mentioned, there's a ton of code to replicate here when overriding this method. Do you have the full code of your override to reference? How did you get past the references to things like _allTipCache? – buddyp450 May 25 '12 at 18:25
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:
- Create a new chart class that extends ChartBase or a child of that.
- Set the ChartBase style,
showDataTipTargets
, to false. - Create a new Style,
showCustomDataTipTargets
, on your custom chart class. - Override
positionDataTips
andpositionAllDatatips
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();
*/
}

- 895
- 1
- 8
- 18
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>

- 130
- 7