Hello-
I've been able to successfully implement Ely's Custom LabelRenderer for
my own purposes (Custom LabelRenderer
http://www.quietlyscheming.com/blog/charts/chart-sampler/ ) however I
was hoping to make it smarter. In my app, I have a Line Chart with my
primary piece of data being modified LineSeries (basically a vertical
line series to plot a spectrum so its a line starting at x,y values and
drawn down to the x-axis) and 3-4 plotseries. My labelRenderer has been
customized to label points from the the plot series I add. The label is
a string about 2-3 chars long, however the nature of my lineseries chart
is such that some line ends up intersecting my labels, and some labels
actually overlap making for a relatively cluttered look. What I was
hoping to do within the labelrenderer is to find out if I have any
points near the point I am labeling, and adjust my labels when needed.
I played a bit with the findDataPoints function within the chart object,
but I'm not 100% sure what I'm doing and it seems as though if I ever
return and hits they are all from the same series and never include
other series hits. Am I on the right track? I am guessing i need to
customize the findAllDatapoints function but I'm not sure where to
start...
Any input is appreciated...
a demo of the app is here:
https://caribou.med.harvard.edu/core/www/giggle/giggle.html
here is the labelRenderer:
package
{
import flash.display.Graphics;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.charts.ChartItem;
import mx.charts.LineChart;
import mx.charts.series.PlotSeries;
import mx.charts.series.items.PlotSeriesItem;
import mx.controls.Label;
import mx.core.IDataRenderer;
import mx.core.UIComponent;
public class LabelRenderer extends UIComponent implements
IDataRenderer
{
private var _label:Label;
public function LabelRenderer()
{
super();
_label = new Label();
addChild(_label);
}
private var _chartItem:ChartItem;
private var _chart:LineChart;
[Inspectable(environment=none)]
public function get data():Object
{
return _chartItem;
}
public function set data(value:Object):void
{
if (_chartItem == value)
return;
_chartItem = ChartItem(value);
var out:String;
if (_chartItem != null) {
if (this.data.item.bmatch ==
PlotSeriesItem(_chartItem).xNumber) {
out = b+value.item.Nnum;
_label.text = out;
_label.setStyle(color, 0x0066FF);
fill = fills[0];
}
else if (this.data.item.ymatch ==
PlotSeriesItem(_chartItem).xNumber) {
out = y+value.item.Cnum;
_label.text = out;
_label.setStyle(color, 0xFF0033);
fill = fills[1];
}
}
}
private static const fills:Array = [0x0066FF,0xFF0033];
private var fill:Number;
override protected function
updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void {
super.updateDisplayList(width, height);
//var fill:Number = fills[5];
//var rc:Rectangle = new Rectangle(0,0, width, height);
var series:PlotSeries = PlotSeries(this.parent);
_chart = LineChart(series.owner);
var pt:Point = _chart.contentToLocal(new
Point(PlotSeriesItem(_chartItem).x,PlotSeriesItem(_chartItem).y));
//var array:Array =
_chart.findDataPoints(PlotSeriesItem(_chartItem).x,PlotSeriesItem(_chart\
Item).y);
var array:Array = _chart.findDataPoints(pt.x,pt.y);
trace(checking for points around
+PlotSeriesItem(_chartItem).x+,+PlotSeriesItem(_chartItem).y+ peak
is:+PlotSeriesItem(_chartItem).xNumber);
trace(checking for points around +pt+ peak
is:+PlotSeriesItem(_chartItem).xNumber);
//checking to see if anything on our chart is within the
width of the label, if so we can move it
if (array.length 1) {
trace(found some stuff overlapping with my chartItem:
+PlotSeriesItem(_chartItem).xNumber);
//trace(array);
}
var rc:Rectangle = new Rectangle(2.5,3.5, 5,5);
var g:Graphics = graphics;
g.clear();
g.moveTo(rc.left, rc.top);
g.beginFill(fill)
g.lineTo(rc.right, rc.top);
g.lineTo(rc.right, rc.bottom);
g.lineTo(rc.left, rc.bottom);
g.lineTo(rc.left, rc.top);
g.endFill();
//g.clear();