Reputation: 130
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.
Upvotes: 1
Views: 1374
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:
showDataTipTargets
, to false.showCustomDataTipTargets
, on your custom chart class.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
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
Reputation: 7294
If you want to remove those circles, set property showDataTipTargets
of chart to false
. If you want to customize them, you can:
dataTipRenderer
and perform skinning and drawing there.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