Scrolling Flex Charts
If your TextArea has a lot of text, you get a scroll bar. If your datagrid has too many rows or columns, you get scroll bars. If your Image is too large, you can put it inside a container with scrollbars. Charts, however, do not have scrollbars. Charts with too much data look like this:
I suppose it doesn't look too bad, but it is impossible to read the x-axis column labels. And of course, the dataset could be even bigger and the chart would be more unreadable.
You could put the chart inside a container with scroll bars, but that has a problem: the vertical axis scrolls out of view:
I'm facing this problem now, so I created a component called 'ScrollableAxisRenderer'. It's derived from AxisRenderer and used in place of an AxisRenderer. Here's what it gives you:
The scrollbar bits are skinnable. This example also has a zoom slider.
I suppose the zoom would be better if the bottom gutter didn't jump around. But I don't really need it right now, so I'm not going to worry about it. I just threw it in for the heck of it.
BarCharts are also supported.
How it works:
The ScrollableAxisRenderer contains another custom component: ChartDataScrollBar. When linked with the chart, it grabs the chart's dataprovider, wraps it in a SubRangeArrayColection and sets the chart's data provider to that. SubRangeArrayCollection implements IList and reveals only a subset of the inner collection; i.e. it acts as a filter. In psuedo-code:
chart.dataProvider = newSubRangeArrayCollection( chart.dataProvider,nColumns,iStartColumn);
The scrollbar's scrollPosition is bound to the SubRangeArrayCollection's startColumn property. Moving the scrollbar changes the data subset that the chart sees.
Note: While it would be easier to set the filterFunction property on the original collection, that would make the data unshareable. For example, if 2 charts were using that same collection as a dataprovider, using the filterFunction property for the first chart would break the second.
The next hurdle is getting the vertical range to stay fixed (in the case of a ColumnChart). As I scrolled the data, the axis values would jump around like crazy as the chart recalculated the optimal vertical range. I found that simply setting the min and max on the axis to themselves made them explicitly set. They were no longer recalculated as the data changed, and they did not jump around anymore.
axis.minimum = axis.minimum; axis.maximum = axis.maximum;
I'm sure it has bugs in it. If you find anything, please let me know. If you have any suggestions about how to code it better, I would appreciate it. The updateProperties(), measure(), etc. are a bit voodoo-ish to me. When something should be updated in updateproperties() vs. updateDisplayList() is sometimes ambiguous.
The scrollbar skinning for this thing has a nasty hack. The ChartDataScrollBar wraps the Flex ScrollBar component which has a hard-coded minimum width of 16. I tried using that width here, but it looked ugly on top of the chart's axis. It really needs to be the same width as the axis, which is about 10 pixels. I can't override the 16-pixel value because the number is private (or internal or whatever). Therefore, I made the scrollbar skins 16 pixels wide, but half the width is invisible (alpha = 0). If you skin this thing, do the same thing. If you scale-9 the thumb, only include the ends of the thumb, not the width. If you change the axis stroke width, you'll have to fix the skin.
Again, if anyone has a better solution, please share it.