From 2015ca3a84cb31c9299a2fca0c50bd49eed2ab29 Mon Sep 17 00:00:00 2001 From: "olau@iola.dk" Date: Fri, 7 Mar 2008 13:33:47 +0000 Subject: [PATCH] Added more members to the Plot object + a few cleanups git-svn-id: https://flot.googlecode.com/svn/trunk@57 1e0a6537-2640-0410-bfb7-f154510ff394 --- API.txt | 33 ++++- NEWS.txt | 5 + examples/basic.html | 3 +- jquery.flot.js | 292 ++++++++++++++++++++++++-------------------- 4 files changed, 196 insertions(+), 137 deletions(-) diff --git a/API.txt b/API.txt index 1475bb7..6276aa5 100644 --- a/API.txt +++ b/API.txt @@ -513,6 +513,37 @@ members: - getPlotOffset() Gets the offset that the grid has within the canvas as an object - with the members left, right, top, bottom. I.e., if you draw a + with the members "left", "right", "top", "bottom". I.e., if you draw a circle on the canvas with the center placed at (left, top), its center will be at the top-most, left corner of the grid. + + - setData(data) + + You can use this to reset the data used. Note that axis scaling, + ticks, legend etc. will not be recomputed (use setupGrid() to do + that). You'll probably want to call draw() afterwards. + + - getData() + + Returns the data currently used. The data series returned are + normalized with missing settings filled in. So for instance to + find out what color Flot has assigned to the data series, you + could do this: + + var series = plot.getData(); + for (var i = 0; i < series.length; ++i) + alert([i].color); + + - setupGrid() + + Recalculate and set axis scaling, ticks, legend etc. + + Note that because of the drawing model of the canvas, this + function will immediately redraw (actually reinsert in the DOM) + the labels and the legend, but not the actual tick lines because + they're drawn on the canvas. You need to call draw() to get the + canvas redrawn. + + - draw() + + Redraws the canvas. diff --git a/NEWS.txt b/NEWS.txt index 086de91..bfa6b73 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -15,6 +15,11 @@ Support for colored background areas via grid.coloredAreas. Specify an array of { x1, y1, x2, y2 } objects or a function that returns these given { xmin, xmax, ymin, ymax }. +More members on the plot object (report by Chris Davies and others). +"getData" for inspecting the assigned settings on data series (e.g. +color) and "setData", "setupGrid" and "draw" for updating the contents +without a total replot. + The default number of ticks to aim for is now dependent on the size of the plot in pixels. Support for customizing tick interval sizes directly with axis.minTickSize and axis.tickSize. diff --git a/examples/basic.html b/examples/basic.html index afd7ac1..8a992a7 100644 --- a/examples/basic.html +++ b/examples/basic.html @@ -20,6 +20,7 @@ scaled.

diff --git a/jquery.flot.js b/jquery.flot.js index 45be7d0..59ee5c6 100644 --- a/jquery.flot.js +++ b/jquery.flot.js @@ -88,34 +88,34 @@ yLabelMaxWidth = 0, yLabelMaxHeight = 0, xLabelBoxWidth = 0, canvasWidth = 0, canvasHeight = 0, plotWidth = 0, plotHeight = 0, - hozScale = 0, vertScale = 0; - - // dedicated to storing data for buggy standard compliance cases - var workarounds = {}; + hozScale = 0, vertScale = 0, + // dedicated to storing data for buggy standard compliance cases + workarounds = {}; + + this.setData = setData; + this.setupGrid = setupGrid; + this.draw = draw; + this.clearSelection = clearSelection; + this.setSelection = setSelection; + this.getCanvas = function() { return canvas; }; + this.getPlotOffset = function() { return plotOffset; }; + this.getData = function() { return series; }; + this.getAxes = function() { return { xaxis: xaxis, yaxis: yaxis }; }; // initialize - series = parseData(data_); parseOptions(options_); - fillInSeriesOptions(); - + setData(data_); constructCanvas(); - bindEvents(); - findDataRanges(); - setRange(xaxis, options.xaxis); - prepareTickGeneration(xaxis, options.xaxis); - setTicks(xaxis, options.xaxis); - extendXRangeIfNeededByBar(); - setRange(yaxis, options.yaxis); - prepareTickGeneration(yaxis, options.yaxis); - setTicks(yaxis, options.yaxis); - setSpacing(); + setupGrid(); draw(); - insertLegend(); - this.getCanvas = function() { return canvas; }; - this.getPlotOffset = function() { return plotOffset; }; - this.clearSelection = clearSelection; - this.setSelection = setSelection; + + function setData(d) { + series = parseData(d); + + fillInSeriesOptions(); + processData(); + } function parseData(d) { var res = []; @@ -145,47 +145,80 @@ options.yaxis.ticks = options.yaxis.noTicks; } - function constructCanvas() { - canvasWidth = target.width(); - canvasHeight = target.height(); - target.html(""); // clear target - target.css("position", "relative"); // for positioning labels and overlay - - if (canvasWidth <= 0 || canvasHeight <= 0) - throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight; - - // the canvas - canvas = $('').appendTo(target).get(0); - if ($.browser.msie) // excanvas hack - canvas = window.G_vmlCanvasManager.initElement(canvas); - ctx = canvas.getContext("2d"); + function fillInSeriesOptions() { + var i; + + // collect what we already got of colors + var neededColors = series.length; + var usedColors = []; + var assignedColors = []; + for (i = 0; i < series.length; ++i) { + var sc = series[i].color; + if (sc != null) { + --neededColors; + if (typeof sc == "number") + assignedColors.push(sc); + else + usedColors.push(parseColor(series[i].color)); + } + } + + // we might need to generate more colors if higher indices + // are assigned + for (i = 0; i < assignedColors.length; ++i) { + neededColors = Math.max(neededColors, assignedColors[i] + 1); + } - // overlay canvas for interactive features - overlay = $('').appendTo(target).get(0); - if ($.browser.msie) // excanvas hack - overlay = window.G_vmlCanvasManager.initElement(overlay); - octx = overlay.getContext("2d"); + // produce colors as needed + var colors = []; + var variation = 0; + i = 0; + while (colors.length < neededColors) { + var c; + if (options.colors.length == i) // check degenerate case + c = new Color(100, 100, 100); + else + c = parseColor(options.colors[i]); - // we include the canvas in the event holder too, because IE 7 - // sometimes has trouble with the stacking order - eventHolder = $([overlay, canvas]); - } + // vary color if needed + var sign = variation % 2 == 1 ? -1 : 1; + var factor = 1 + sign * Math.ceil(variation / 2) * 0.2; + c.scale(factor, factor, factor); - function bindEvents() { - if (options.selection.mode != null) { - eventHolder.mousedown(onMouseDown); + // FIXME: if we're getting to close to something else, + // we should probably skip this one + colors.push(c); - // FIXME: temp. work-around until jQuery bug 1871 is fixed - eventHolder.each(function () { - this.onmousemove = onMouseMove; - }); + ++i; + if (i >= options.colors.length) { + i = 0; + ++variation; + } } - if (options.grid.clickable) - eventHolder.click(onClick); - } + // fill in the options + var colori = 0, s; + for (i = 0; i < series.length; ++i) { + s = series[i]; + + // assign colors + if (s.color == null) { + s.color = colors[colori].toString(); + ++colori; + } + else if (typeof s.color == "number") + s.color = colors[s.color].toString(); - function findDataRanges() { + // copy the rest + s.lines = $.extend(true, {}, options.lines, s.lines); + s.points = $.extend(true, {}, options.points, s.points); + s.bars = $.extend(true, {}, options.bars, s.bars); + if (s.shadowSize == null) + s.shadowSize = options.shadowSize; + } + } + + function processData() { xaxis.datamin = yaxis.datamin = Number.MAX_VALUE; xaxis.datamax = yaxis.datamax = Number.MIN_VALUE; @@ -224,6 +257,63 @@ yaxis.datamax = 1; } + function constructCanvas() { + canvasWidth = target.width(); + canvasHeight = target.height(); + target.html(""); // clear target + target.css("position", "relative"); // for positioning labels and overlay + + if (canvasWidth <= 0 || canvasHeight <= 0) + throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight; + + // the canvas + canvas = $('').appendTo(target).get(0); + if ($.browser.msie) // excanvas hack + canvas = window.G_vmlCanvasManager.initElement(canvas); + ctx = canvas.getContext("2d"); + + // overlay canvas for interactive features + overlay = $('').appendTo(target).get(0); + if ($.browser.msie) // excanvas hack + overlay = window.G_vmlCanvasManager.initElement(overlay); + octx = overlay.getContext("2d"); + + // we include the canvas in the event holder too, because IE 7 + // sometimes has trouble with the stacking order + eventHolder = $([overlay, canvas]); + + + // bind events + if (options.selection.mode != null) { + eventHolder.mousedown(onMouseDown); + + // FIXME: temp. work-around until jQuery bug 1871 is fixed + eventHolder.each(function () { + this.onmousemove = onMouseMove; + }); + } + + if (options.grid.clickable) + eventHolder.click(onClick); + } + + function setupGrid() { + // x axis + setRange(xaxis, options.xaxis); + prepareTickGeneration(xaxis, options.xaxis); + setTicks(xaxis, options.xaxis); + extendXRangeIfNeededByBar(); + + // y axis + setRange(yaxis, options.yaxis); + prepareTickGeneration(yaxis, options.yaxis); + setTicks(yaxis, options.yaxis); + + setSpacing(); + insertLabels(); + insertLegend(); + } + function setRange(axis, axisOptions) { var min = axisOptions.min != null ? axisOptions.min : axis.datamin; var max = axisOptions.max != null ? axisOptions.max : axis.datamax; @@ -648,7 +738,6 @@ function draw() { drawGrid(); - drawLabels(); for (var i = 0; i < series.length; i++) { drawSeries(series[i]); } @@ -666,6 +755,7 @@ var i; ctx.save(); + ctx.clearRect(0, 0, canvasWidth, canvasHeight); ctx.translate(plotOffset.left, plotOffset.top); // draw background, if any @@ -749,9 +839,11 @@ } } - function drawLabels() { + function insertLabels() { + target.find(".tickLabels").remove(); + var i, tick; - var html = '
'; + var html = '
'; // do the x-axis for (i = 0; i < xaxis.ticks.length; ++i) { @@ -774,79 +866,6 @@ target.append(html); } - function fillInSeriesOptions() { - var i; - - // collect what we already got of colors - var neededColors = series.length; - var usedColors = []; - var assignedColors = []; - for (i = 0; i < series.length; ++i) { - var sc = series[i].color; - if (sc != null) { - --neededColors; - if (typeof sc == "number") - assignedColors.push(sc); - else - usedColors.push(parseColor(series[i].color)); - } - } - - // we might need to generate more colors if higher indices - // are assigned - for (i = 0; i < assignedColors.length; ++i) { - neededColors = Math.max(neededColors, assignedColors[i] + 1); - } - - // produce colors as needed - var colors = []; - var variation = 0; - i = 0; - while (colors.length < neededColors) { - var c; - if (options.colors.length == i) // check degenerate case - c = new Color(100, 100, 100); - else - c = parseColor(options.colors[i]); - - // vary color if needed - var sign = variation % 2 == 1 ? -1 : 1; - var factor = 1 + sign * Math.ceil(variation / 2) * 0.2; - c.scale(factor, factor, factor); - - // FIXME: if we're getting to close to something else, - // we should probably skip this one - colors.push(c); - - ++i; - if (i >= options.colors.length) { - i = 0; - ++variation; - } - } - - // fill in the options - var colori = 0; - for (i = 0; i < series.length; ++i) { - var s = series[i]; - - // assign colors - if (s.color == null) { - s.color = colors[colori].toString(); - ++colori; - } - else if (typeof s.color == "number") - s.color = colors[s.color].toString(); - - // copy the rest - s.lines = $.extend(true, {}, options.lines, s.lines); - s.points = $.extend(true, {}, options.points, s.points); - s.bars = $.extend(true, {}, options.bars, s.bars); - if (s.shadowSize == null) - s.shadowSize = options.shadowSize; - } - } - function drawSeries(series) { if (series.lines.show || (!series.bars.show && !series.points.show)) drawSeriesLines(series); @@ -1256,6 +1275,8 @@ } function insertLegend() { + target.find(".legend").remove(); + if (!options.legend.show) return; @@ -1298,7 +1319,7 @@ pos += 'right:' + (m + plotOffset.right) + 'px;'; else if (p.charAt(1) == "w") pos += 'left:' + (m + plotOffset.bottom) + 'px;'; - var div = $('
' + table + '
').appendTo(target); + var legend = $('
' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(target); if (options.legend.backgroundOpacity != 0.0) { // put in the transparent background // separately to avoid blended labels and @@ -1309,10 +1330,11 @@ if (options.grid.backgroundColor != null) tmp = options.grid.backgroundColor; else - tmp = extractColor(div); + tmp = extractColor(legend); c = parseColor(tmp).adjust(null, null, null, 1).toString(); } - $('
').appendTo(target).css('opacity', options.legend.backgroundOpacity); + var div = legend.children(); + $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity); } }