Перевод: Игорь Карпов igorok.karpov@gmail.com При поддержке www.php5.com.ua Если вы можете улучшить перевод документации или примеров, свяжитесь со мной. Документация по Flot -------------- Рассмотрим вызов функции plot: var plot = $.plot(placeholder, data, options) placeholder - контейнер в который jQuery ложит график. У него должна быть задана ширина и высота. Как их задать, можно почитать в README (это не займет много времени). В качестве плейсхолдера подойдет обычный div. Формат данных описывается ниже и он доступен, как опции. Плагин "plot" возвращает объект, методы которого вы можете вызывать. Методы описаны ниже. Результат нормальной работы вам не гарантирован, если вы будете вносить изменения в сам плагин:) Формат данных ----------- Данные представляются в виде последовательности: [ series1, series2, ... ] Последовательность может быть любой из двух. Это могут быть необработанные данные или объекты со своими свойствами. Необработанные данные заданются в виде массива точек: [ [x1, y1], [x2, y2], ... ] или [ [1, 3], [2, 14.01], [3.5, 3.14] ] Для упрощения внутренней логики в Flot как X так и Y должны быть числами, даже, если вы задаете временные последовательности (смотрите ниже, как это сделать). Это является проблемой, т.к. вы могли получить даные из БД, сериализировать их в JSON и не получить сообщения о неправильном типе данных. Если точка задана, как null или одна из координат задана, как null или не может быть преобразована в число, то эта точка бдет игнорироваться при построении. В особых случаях значения типа null интерпретируются, как конец отрезка, т.е. точки до и после значений типа null соединены не будут. Формат одиночной последовательности объекта следующий: { color: color or number data: rawdata label: string lines: specific lines options bars: specific bars options points: specific points options xaxis: number yaxis: number clickable: boolean hoverable: boolean shadowSize: number } Не все параметры являются обязательными, достаточно задать label и data, как показано в примере ниже, остальные параметры будут установлены по умолчанию: { label: "y = 3", data: [[0, 3], [10, 3]] } label используется для задания легенды графика, если значение не установлено, то легенда не отобразится на графике. Если не указать значение color, то цвет сгенерируется автоматически. цвет можно задавать любой описанный в спецификаии CSS (например, "rgb(255, 100, 123)") или целым числом, на основе которого цвета будут сгенерированы автоматически. 0 соответствует цвету с кодом 0 и т.д... Последнее в основном полезно, если дать пользователю возможность самому задавать последовательности. В этом случае цвет графика можно захардкодить, что бы цвет графиков не менялся сам по себе. Параметры "xaxis" и "yaxis" задают какую из осей использовать, задайте 2 что бы получить вторую ось(ось х сверху или ось y справа). Например, что бы получить двухмерный график вы можете задать {yaxis:2} для одной последовательности данных. Остальные необязательные параметры описаны ниже. Если их не задавать, то они примут значения по умолчанию, при построении графика. Пример, построение графика с минимальным набором параметров: [ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] }, { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] } ] Параметры ------------ Все параметры описанные ниже, являются необязательными параметрами. Каждый из них описан ниже. Их необходимо задавать в объекте, например var options = { lines: { show: true }, points: { show: true } }; $.plot(placeholder, data, options); Как задать легенду ====================== legend: { show: boolean labelFormatter: null or (fn: string, series object -> string) labelBoxBorderColor: color noColumns: number position: "ne" or "nw" or "se" or "sw" margin: number of pixels or [x margin, y margin] backgroundColor: null or color backgroundOpacity: number between 0 and 1 container: null or jQuery object/DOM element/jQuery expression } Легенда это таблица с расшифровкой цветов графиков. Если вы хотите как-то изменить легенду, например, на подпись к цвету поставить ссылку, необходимо задать функцию для параметра "labelFormatter", как в примере ниже: labelFormatter: function(label) { return '' + label + ''; } "noColumns" задает количество столбцов легенды. "position" задает позицию легенды на сетке (top-right, top-left, и т.д.) и отступ от края сетки. "backgroundColor" и "backgroundOpacity" задают фон. По умолчанию частичная прозрачность, автодетектится сама. Если вы хотите легендировать где-нибудь в другом месте, вы должны задать контейнер, в который jQuery положит легенду. Тогда параметры "position" и "margin" будут игнориться. Естественно, содержимое контейнера будет затерто легендой. Как задать оси ==================== xaxis, yaxis: { show: null or true/false position: "bottom" or "top" or "left" or "right" mode: null or "time" color: null or color spec tickColor: null or color spec font: null or font spec object min: null or number max: null or number autoscaleMargin: null or number transform: null or fn: number -> number inverseTransform: null or fn: number -> number ticks: null or number or ticks array or (fn: axis -> ticks array) tickSize: number or array minTickSize: number or array tickFormatter: (fn: number, object -> string) or string tickDecimals: null or number labelWidth: null or number labelHeight: null or number reserveSpace: null or true tickLength: null or number alignTicksWithAxis: null or number } Оси имеют несколько видов опций. "mode" - задает, как данные будут интерпретироваться, по умолчанию null, интерпретируется, как десятичное число. "time" - используется для задания последовательностей временных данных, описание читайте ниже. "min"/"max" - определяет крайние значения шкалы. Если их не задавать, то градация установится автоматически на основе переданных данных. "autoscaleMargin" - немного таинственный параметр. Это часть отступа, которая масштабирует алгоритм добаления избегая крайние значения конечной точки от края сетки. Эта опция необходима тогда, когда заданы минимальное и максимальное значения. If a margin is specified, the plot will furthermore extend the axis end-point to the nearest whole tick. "null" - Значени по умолчанию для оси х и 0.02 для оси y, что подходит для большинства случаев. "labelWidth" и "labelHeight" задают в пикселах максимальную высоту и ширину лейбла легенды specifies the maximum size of the tick labels in pixels. They're useful in case you need to align several plots. Следующие параметры задают свойства меток. Если вы не зададите метки, генератор меток сделает это за вас. Алгоритм генерации имеет два варианта. Генерация может происходить двумя способами. Первый выбирает наиболее подходящие метки и использует их для подсчета округленных интервалов. После этого генерирует метки. Вы можете задать количество меток для для расчета одного числа. Алгоритм всегда старается сгенерировать наиболее лучшие значения меток, так, если вы зададите три метки, то можете получить пять наиболее лучших с округлением. Если вы не хотите задавать метки, задайте параметр "ticks" нулевым или пустым массивом. Второй вариант заключается в игнорировании части округлений и непосредственном задании размера интервала меток параметром "tickSize". Если вы зададите 2, то получите последовательность 2, 4, 6 и т.д... Кроме того, вы можете указать, что вы просто не хотите иметь метки меньшие за конкретное значение в параметре "minTickSize". клещей на один размер меньше, чем конкретный размер галочку с Заметим, что для временных последовательностей, формат представляет собой массив [2, "месяц"], см. следующий раздел. Если вы хотите полностью переопределить алгоритм задания меток, то вам необходимо задать массив меток, например, так: ticks: [0, 1.2, 2.4] Или так (вы можете смешать два, если хотите): ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]] Для большей гибкости, вы можете задать функцию, как "ticks" параметр. Эта функция должна вызываться с объектом axis (ось) свойствами которого есть минимальное и максимальное значения и возвращать массив. Ниже приведен упрощенный генератор меток, который разбивает ось Х на интервалы с шагом значения числа pi для тригонометрических функций: function piTickGenerator(axis) { var res = [], i = Math.floor(axis.min / Math.PI); do { var v = i * Math.PI; res.push([v, i + "\u03c0"]); ++i; } while (v < axis.max); return res; } Вы можете контролировать вид меток при помощи параметра "tickDecimals", число знаков после запятой (по умолчанию автодетектится). Кроме того, для полного контроля вида меток можно ввести функцию "tickFormatter". Функция имеет два входных параметра - это значение метки и "axis" объект с информацией. Она возвращает строку. По умолчанию она выглядит так: function formatter(val, axis) { return val.toFixed(axis.tickDecimals); } Объект "axis" имеет свойства "min" and "max" с диапазоном оси, "tickDecimals" - число знаков после запятой при округлении и "tickSize" - размер интервала между метками, он вычисляется автоматически или может быть задан "руками". Ниже пример пользовательского форматирования меток: function suffixFormatter(val, axis) { if (val > 1000000) return (val / 1000000).toFixed(axis.tickDecimals) + " MB"; else if (val > 1000) return (val / 1000).toFixed(axis.tickDecimals) + " kB"; else return val.toFixed(axis.tickDecimals) + " B"; } Временные последовательности ================ Временные последовательности немного сложнее, чем работа со скалярными данными, т.к. календарь не поддается описанию в десятичной системе счисления. В большинстве случаев Flot это абстрактная величина, но могут возникнуть трудности с получением даных для построения временных графиков, поэтому сначала обсудим формат данных. Временные последовательности в Flot основаны на таймстемпе в Javascript, т.е. везде значение времени ожидаемое или передаваемое должно быть приведено к таймстемпу, который используется в Javascript. Это значение не является Date объектом. Таймстемп в Javascript это число в милисекундах с 1го января 1970 00:00:00 UTC. Это почти тоже самое, как и таймстемп в Unix, только в милисекундах, поэтому не забываем множить на 1000. Как получить таймстемп: alert((new Date()).getTime()) Было бы неплохо, отображать время в соответствии с временной зоной. Однако, Flot всегда отображает время по Гринвичу. Учитывая особенности языка Javascript, он выдает тот часовой пояс, в котором находится посетитель. Из-за этого могут возникать непредсказуемые смещения времени для каждого посетителя. Во избежании таких проблем, о данных времени необходимо позаботиться на стороне сервера. Самый простой способ заключается в том, что бы представлять данные в часовом поясе по гринвичу, даже если это не так. Т.е. если мы имеем точку времени 2002-02-20 08:00, то лучше ее задать, как 8 часов по грнивичу, даже если это произошло в 8 +2 часа по гринвичу. В PHP соответствующее время будет выглядеть так 'strtotime("2002-02-20 UTC") * 1000', в Python так 'calendar.timegm(datetime_object.timetuple()) * 1000', в .NET примерно так: public static int GetJavascriptTimestamp(System.DateTime input) { System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks); System.DateTime time = input.Subtract(span); return (long)(time.Ticks / 10000); } Javascript также есть поддержка парсинга дат, так что есть возможность генерировать временные данные на стороне клиента. Если вы уже получили данные времени по гринвичу, то уже поздно делать трюк с "обманом", описанным выше. Но можно зафиксить это путем добавления смещения часового пояса, т.е. для UTC+0200 необходимо добавить +2 часа к времени по гринвичу, которое вы получили. И это будет корректно отображаться на графике. Главное иметь какой-то инструмент для определения часового пояса. После того, как время приведено к нормальному формату и задана ось в качестве временной, Flot автоматически сгенерирует соответствующие метки и их формат. Как всегда, метки настраиваются через параметр "tiks". Помните, что значения должны быть числами, а не объетом Date. Генерацию меток и их форматирование можно задать следующим кодом: xaxis, yaxis: { minTickSize timeformat: null или формат строки monthNames: null или array of size 12 of strings } Параметр "timeformat" задает строки даты на графике. Задать можно, например, так: xaxis: { mode: "time", timeformat: "%y/%m/%d" } В результате будет метка будет подписана так: "2000/12/24". Поддерживаются следующие параметры для задания формата даты %h': часы %H': часы (дополняются нулем впереди) %M': минуты (дополняются нулем впереди) %S': секунды (дополняются нулем впереди) %d': день месяца (1-31) %m': месяц (1-12) %y': год (4 цифры) %b': название месяца (изменяемое) Названия месяцов можно менять, задав параметр "monthNames". Для России это будет выглядеть так: monthName: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"] Также форматирование меток можно задать при помощи функции. Ниже приведен пример, который преобразует 24 декабря в 24/12: tickFormatter: function (val, axis) { var d = new Date(val); return d.getUTCDate() + "/" + (d.getUTCMonth() + 1); } Следует отметить, что временные параметры "tickSize" и "minTickSize" немного особенные тем, что это массивы формата "[value, unit]", где unit принимает значения "second", "minute", "hour", "day", "month" и "year". Пример ниже: minTickSize: [1, "month"] код задает интервал между метками не менее месяца. Если задать для axis.tickSize значени [2, "day"], то интервал между метками будет составлять два дня. Настройка последовательностей данных =========================== lines, points, bars: { show: boolean lineWidth: number fill: boolean or number fillColor: color } points: { radius: number } bars: { barWidth: number align: "left" or "center" } colors: [ color1, color2, ... ] shadowSize: number "lines", "points" и "bars" - самые важные параметры, которые задают внешний вид линий графиков, точек и столбцов. Вы можете задать их независимо друг от друга, например var options = { lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" }, points: { show: true, fill: false } }; "lineWidth" - задает толщину линии в пикселах. "fill" задает, должна ли быть залита область графика. Цвет заливки задается параметром "fillColor". Если "fillColor" установлен в false (по умолчанию на все, кроме точек), то цвет заливки установится автоматически в цвет последовательности данных. Вы можете настроить прозрачность заливки, задав значени от 0 (полностью прозрачный) и 1 (полностью непрозрачный). "barWidth" задает ширину столбца в единицах оси Х, а не в пикселах, как в большинстве случаев. Например, для временных последовательностей одна единица задается в милисекундах следующим образом 24 * 60 * 60 * 1000, что задаст столбцы шириной в один день. "align" - задает, выравниваение столбца, левое выравниевание (по умолчанию) или центрирование к верхнему значению. "colors" - массив, задающий цветовую тему по умолчанию. Можно задать множество цветов, которые вам нравятся, например, так: colors: ["#d18b2c", "#dba255", "#919733"] Если графиков будет больше, чем заданных цветов, то Flot будет придавать различные оттенки цветам из заданной темы. "shadowSize" - по умолчанию размер тени в пикселях. Для того, что бы убрать тени, установите его в 0. Настройка сетки ==================== grid: { color: color backgroundColor: color or null tickColor: color labelMargin: number markings: array of markings or (fn: axes -> array of markings) borderWidth: number clickable: boolean hoverable: boolean autoHighlight: boolean mouseActiveRadius: number } Сетка это оси с засечками на них. The grid is the thing with the axes and a number of ticks. "color" - задает сам цвет сетки "backgroundColor" - задает цвет фона сетки, по умолчанию принимает значение null, это значит, что фон прозрачный. Задайте только "backgroundColor", если хотите, что бы сетка отличалась по цвету от цвета страницы. В противном случае, вы можете установить цвет фона страницы через CSS. "tickColor" - задает цвет меток "labelMargin" - задает расстояние между меткой и сеткой. Заметим, что стиль меток можно задать через CSS, сменив цвет. За это отвечает класс "tickLabel". "borderWidth" - задает ширину рамки по краю сетки. Для того что бы скрыть рамку, необходимо этот параметр установить в 0. "markings" - используется для отрисовки простых линий и прямоугольных областей на фоне графика. Вы можете задать либо массив, который колеблется на промежутке { xaxis: { from, to }, yaxis: { from, to } } (вторичные оси координат с x2axis/y2axis) или функцию, которая возвращает аналогичный массив. Вы можете либо задать массив последовательности вида { xaxis: { from, to }, yaxis: { from, to } } (вторичные оси координат с x2axis/y2axis) или функцию, котра вернет такой же массив в объекте с первым параметром. Вы можете задать цвет маркировки параметром "color". markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 10, to: 10 }, color: "#bb0000" }, ... ] Если оставить только одно из значений, например, { xaxis: { from: 0, to: 2 } } , то это будет значить, что область будет ограничена по оси Х диапазоном 0-2, а по оси Y минимальным и максимальным значениями самого графика. A line is drawn if from and to are the same, e.g. markings: [ { yaxis: { from: 1, to: 1 } }, ... ] отрисуетлинию параллельную оси Х в значении y = 1. Можно задавать ширину линии параметром "lineWidth" Например, так: markings: function (axes) { var markings = []; for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2) markings.push({ xaxis: { from: x, to: x + 1 } }); return markings; } Если параметру "clickable" присвоить значени true, то график будет ожидать события click и возбудится событие "plotclick" в контейнере с данными позиции и данными соседей, как параметры объекта. Координаты будут доступны как единицы измерения оси (не в пикселах) и глоабальные координаты экрана. Аналогично, если параметру "hoverable" установить значение true, то будет одидаться событие наведения курсора мыши на график и возбудится событие "plothover", с параметрами аналогичными событию "plotclick". Если параметр "autoHighlight" - истина (по умолчанию), то данные, которые находятся рядом выделятся автоматически. При необходимости выделение можно отключить, для личного контроля испольщзуются методы highlight/unhighlight, которые будут рассмотрены ниже. События "plotclick" и "plothover" можно использовать, например, так: $.plot($("#placeholder"), [ d ], { grid: { clickable: true } }); $("#placeholder").bind("plotclick", function (event, pos, item) { alert("You clicked at " + pos.x + ", " + pos.y); // secondary axis coordinates if present are in pos.x2, pos.y2, // if you need global screen coordinates, they are pos.pageX, pos.pageY if (item) { highlight(item.series, item.datapoint); alert("You clicked a point!"); } }); Объект item в этом примере либо null, либо соседний объект формы: item: { datapoint: the point as you specified it in the data, e.g. [0, 2] dataIndex: the index of the point in the data array series: the series object seriesIndex: the index of the series pageX, pageY: the global screen coordinates of the point } Например, если задать данные следующим образом $.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...); и подвести курсор близко к точке (7, 3), параметру "datapoint" мы задали значение [7, 3], "dataIndex" будет 1, "series" упорядоченные последовательности объектов среди других значений метки "Foo" в series.label и цвет в series.color, и "seriesIndex" со значением 0. Если вы используете события выше для обновления какой-то другой информации и хотите очищать эту информацию в случае, если мышь "уходит", то поможет событие "mouseout" для контейнера div. "mouseActiveRadius" задает область реакции вокруг точки. Если в области события две точки, то выбирается ближайшая точка. Для диаграм, самый высокий приоритет у выбранного столбца. Настройка выделенной области (подсветки выбранной области) ========================= selection: { mode: null or "x" or "y" or "xy", color: color } Вы можете разрешить выделение задав "x", "y" или "xy". В режиме "х", пользователь может задавать диапазон только по оси Х, аналогично в режиме "у". В режиме "ху", выделение будет производиться прямоугольником по обоим осям. "color" задает звет быделения. Если поддержка выделения включена, то событие "plotselected" сработает на DOM элемент, его можно передать в функцию plot. Событие получит дополнительный параметр с диапазоном выбранных осей, например: placeholder.bind("plotselected", function(event, ranges) { alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to) // similar for yaxis, secondary axes are in x2axis // and y2axis if present }); Методы Plot ------------ Объект Plot, который возвращает функция plot имеет несколько методов, которые вы можете вызывать: - clearSelection() Очищает выделенный прямоугольник - setSelection(ranges, preventEvent) Устанавливает выделение прямоугольника. входящий параметр ranges это данные возвращаемые в результате вызова события "plotselected". Если тип выделения "х", вы передадите объект xaxis (или x2axis), если тип выделения "y" вы передадите объект yaxis (или y2axis) и оба xaxis/x2axis и yaxis/y2axis, если тып выделения "xy", например: setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } }); setSelection приведет в действие событие "plotselected". Если вы не хотите этого, то задайте вторым параметром true. - highlight(series, datapoint) Подсвечивает заданные точки в последовательности. Вы можете либо задать объекты, например, если вы хотите получить их по событию "plotclick" или задать индексы, например highlight(1, 3) для подсветки четвертой точки во второй последовательности. - unhighlight(series, datapoint) Убирает подсветку с подсвеченных точек, параметры аналогичны методу highlight. - setData(data) Используйте этот метод для сброса текущих значений. Заметим, что масштаб осей, метки, легенда и т.д. тоже можно менять (для этого используйте setupGrid()). Возможно, потом вы захотите вызвать метод draw(). Вы можете использовать этот метод для быстрой перерисовки графика, если вы уверены, что оси не будут меняться и затем вызвать draw(). - setupGrid() Пересчитывает и устанавливает масштаб осей, меток, легенды и т.д... Заметим, что этот метод сразу же изменит метки и легенду, но не перерисует сам график, для этого необходимо вызвать метод draw(). - draw() Перерисовывает канву. Бывают очень любопытные люди, которые могут полезть внутрь Flot, иногда это бывает полезно. Но следует помнить, что если вы изменяете что-то в возвращаемом значении объекта, то вы меняете объект, который использует Flot и с этим нужно быть аккуратным. - getData() Возвращает массив последовательности данных, в нормальной форме с заполненными пропущенными параметрами в соответствии с заданными опциями. Например, что бы узнать, какой цвет Flot присвоил к последовательности, необходимо сделать так: var series = plot.getData(); for (var i = 0; i < series.length; ++i) alert(series[i].color); - getAxes() Получает объект, который хранит настройки осей { xaxis, yaxis, x2axis, y2axis }. Например, вы можете использовать код getAxes().xaxis.ticks для нахождения точек на оси xaxis. - getCanvas() Возвращает канву, используемую для отрисовки в случае, если вы хотите делать какие-то хаки для себя. Так же, возможно, вы захотите получить смещение графика. - getPlotOffset() Получает смещение, которое сетка имеет внутри канвы как объект с расстоянием от края как "left", "right", "top", "bottom". Т.е если вы рисуете круг на канве с центром (left, top), этот центр будет в левом верхнем углу сетки.