В одном из предыдущих постов я рассказывала о решении проблемы пропадающих DataTip-ов в LineSeries с нефильтрованными данными (т.е filterData=false).
Как я уже говорила проблема в строке 969 класса mx.charts.series.LineSeries.as:
if (!isNaN(v.yFilter) && !isNaN(v.xFilter))
Не буду приводить исходный код тут. Слишком много букв.
При наследовании мне пришлось не только переопределить findDataPoints, но и воспроизвести приватный метод серии formatDataTip. Фактически же изменения коснулись только findDataPoints. Я добавила ряд проверок, однако оказалось что это был не лучший выход. Здесь народ столкнулся с аналогичной проблемой и нашел гораздо более удачное, на мой взгляд, решение. В findDataPoints они избежали многочисленных проверок заменив вышеупомянутую строку
if (!isNaN(v.yFilter) && !isNaN(v.xFilter)) на
if (!isNaN(v.yNumber) && !isNaN(v.xNumber)).
При работе с чартингом, одной из осей которого является DateTimeAxis, часто возникает потребность в изменении формата отображения меток. Как я поняла в ходе общения с кодом DateTimeAxis, сам флекс не меняет формат даты в зависимости от локали. По умолчания дата отображается в формате m/d/yy. Для российского глаза такое отображение несколько непривычно. Хелп предоставляет два пути решения этой проблемы.
1. labelFunction:Function [read-write]
Called to format axis values for display as labels. A labelFunction has the following signature:
- function labelFunction(labelValue:Object, previousValue:Object, axis:IAxis):String
If you know the types of the data your function will be formatting, you can specify an explicit type for the labelValue and previousValue parameters.
Казалось бы вот оно счастье, однако поспешность в выборе может послужить для вас причиной дополнительного геморроя. Качественная замена функции дело довольно муторное. Ведь интервал между метками может составлять как секунды так и годы. Куча кода. Рекомендую с негодованием отвергнуть эту веселую перспективу и обратить свой взор к пункту 2.
2. В хелпе есть такое понятие как Protected Methods. Для человека пришедшего из AS2 и не озаботившегося ознакомлением с матчастью AS3 такое буквосочетание может показаться слабо информативным, однако белые люди сжевавшие в процессе общения с флексом уже не одну pdf-ную страницу в курсе что Protected Methods - методы класса которые можно переопределять в наследниках. Часто большинство этих методов скрыто в недрах хелпа в аккордеоне с надписью “Show Inherited Protected Methods", однако это не наш случай. Интересующие нас сейчас методы DateTimeAxis на виду:
- formatDays(d:Date, previousValue:Date, axis:DateTimeAxis):String
- formatMilliseconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
- formatMinutes(d:Date, previousValue:Date, axis:DateTimeAxis):String
- formatMonths(d:Date, previousValue:Date, axis:DateTimeAxis):String
- formatSeconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
- formatYears(d:Date, previousValue:Date, axis:DateTimeAxis):String
Разумеется прежде чем переопределять их в соответствии с вашими пожеланиями следует ознакомиться с исходным кодом DateTimeAxis. Там за вас уже все придумали и написали:
- protected function formatYears(d:Date, previousValue:Date, axis:DateTimeAxis):String
- {
- var fy:Number = d[fullYearP];
- return fy.toString();
- }
- protected function formatMonths(d:Date, previousValue:Date, axis:DateTimeAxis):String
- {
- var fy:Number = d[fullYearP];
- return (d[monthP] + 1) + "/" + ((fy % 100) < 10 ? "0" + fy % 100 : fy % 100);
- }
- protected function formatDays(d:Date, previousValue:Date, axis:DateTimeAxis):String
- {
- var fy:Number = d[fullYearP];
- return (d[monthP] + 1) + "/" + d[dateP] + "/" + ((fy % 100) < 10 ? "0" + fy % 100 : fy % 100);
- }
- protected function formatMinutes(d:Date, previousValue:Date, axis:DateTimeAxis):String
- {
- return d[hoursP] + ":" + (d[minutesP] < 10 ? "0" + d[minutesP] : d[minutesP]);
- }
- protected function formatSeconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
- {
- return d[hoursP]+ ":" + (d[minutesP] < 10 ? "0" + d[minutesP] : d[minutesP]) + ":" + (d[secondsP] < 10 ? "0" + d[secondsP] : d[secondsP]);
- }
Потребуется только слегка откорректировать эти методы в соответствии с вашими пожеланиями. Или, если приложение требует некоторой гибкости, добавить к уже имеющемуся формату еще несколько форматов отображения. (в зависимости от локали)
Кстати. Если вдруг получившиеся в ходе переопределения методов метки будут натыкаться друг на друга и делать подписи абсолютно нечитаемыми следует воспользоваться методом reduceLabels(intervalStart:AxisLabel, intervalEnd:AxisLabel):AxisLabelSet, а никак не свойством interval : Number, как это может захотеться с первого взгляда. Но это уже совсем другая история…
10> 10> 10>
Ранее я упоминала о том, что в LineChart с не фильтрованными данными отказываются демонстрироваться DataTips. Эту странность я склонна классифицировать как баг, поскольку с другими чартами такой проблемы у меня не возникло.
Суть проблемы:
При наведении мыши на рабочую область чартинга вызывается метод findDataPoints(x:Number,y:Number,sensitivity:Number):Array mx.charts.series.LineSeries, который проверяет с погрешностью sensitivity соответствие точки mouseX,mouseY пикам серии.
- var v:LineSeriesItem = _renderData.filteredCache[cur];
- if (!isNaN(v.yFilter) && !isNaN(v.xFilter))
- {
- var dist:Number = (v.x - x)*(v.x - x) + (v.y - y)*(v.y -y);
- if (dist <= minDist2)
- {
- minDist2 = dist;
- minItem = v;
- }
- }
в строке if (!isNaN(v.yFilter) && !isNaN(v.xFilter)) на isNaN проверяются значения свойств, которые просто не создаются в случае, когда filterData=false. Происходит это в методе updateFilter():void того же LineSeries.
Решение:
Наследуем LineSeriesNew от LineSeries, в котором и переопределяем метод findDataPoints
При реализации пана и зума в чартинге я столкнулась с тем, что при уходе за пределы отображаемой области какого-то из ключевых значений например значения high свечи CandlestickChart вся свеча благополучно пропадает. На LineChart в этом случае вообще без слез смотреть невозможно. И дело тут не в багах. Причиной свойство filterData серий. Собственно по умолчанию данные фильтруются, что и приводит к подобной фигне.
Однако с отключением фильтрации тоже есть некоторые сложности с одним из которых мне посчастливилось столкнуться. Дело в том что в LineChart с не фильтрованными данными отказываются демонстрироваться DataTips. О причинах и решении этой проблемы я расскажу позднее.
баг:
не работает hlocSeries.setStyle("closeTickStroke", color);
проблема:
строка 116 mx.charts.renderers.HLOCItemRenderer:
- var closeTickStroke:Stroke = getStyle("openTickStroke");
решение:
создаем свой itemRenderer в котором исправляем эту досадную описку
