From b100f441cd3645c2b1dac9e1fe9f62c158eca440 Mon Sep 17 00:00:00 2001 From: Jeff Tian Date: Thu, 28 Nov 2013 11:30:00 +0800 Subject: [PATCH] Enrich the flot with the ability to add text into markings. Use $.isArray instead of instanceof Array; Use full name for parameters. --- API.md | 44 ++++++ examples/index.html | 1 + examples/markings/index.html | 123 +++++++++++++++++ examples/markings/you_are_here.png | Bin 0 -> 14820 bytes jquery.flot.js | 212 +++++++++++++++++++++-------- 5 files changed, 326 insertions(+), 54 deletions(-) create mode 100644 examples/markings/index.html create mode 100644 examples/markings/you_are_here.png diff --git a/API.md b/API.md index f23f7cc..d6d5879 100644 --- a/API.md +++ b/API.md @@ -948,6 +948,50 @@ markings: function (axes) { } ``` +By default, the markings will be drawn under the grid ticks, if you +need to draw a marking above the grid ticks, you can specifiy a +"aboveGrid" attribute and set it to true, e.g. + +```js +markings: [ { xaxis: { from: 1, to: 2 }, yaxis: { from: 1, to: 2 }, aboveGrid: true }, ... ] +``` +Usually a marking is a regular rectangle, when you want it to have a rounded +corner, you can specify a "rounded" value to it, e.g. + +```js +markings: [ { xaxis: { from: 1, to: 2 }, yaxis: { from: 1, to: 2 }, aboveGrid: true, rounded: 3 }, ... ] +``` + +In case you want to put some texts attaching to markings, you can specifiy +an "text" object to the marking object, along with a font object as well as +other 2 attributes (textAlign and textBaseline) to align texts well in the +marking if you want to give the texts a customized look, e.g. + +```js +markings: [ + { + xaxis: { from: 1, to: 2 }, + yaxis: { from: 1, to: 2 }, + aboveGrid: true, + color: "#000", + rounded: 3, + text: "The 1st line.
The 2nd line.", + textAlign: "center", + textBaseline: "middle", + font: { + color: "#fff", + size: "12" + } + }, + ... +] +``` + +As you see from the above code example, you can control the look and feel +of the texts by inline css style, besides this approach, you can also +customize the look and feel of these texts by defining css rules to the +class *flot-marking*, which class the texts has. + If you set "clickable" to true, the plot will listen for click events on the plot area and fire a "plotclick" event on the placeholder with a position and a nearby data item object as parameters. The coordinates diff --git a/examples/index.html b/examples/index.html index e91016a..baf636e 100644 --- a/examples/index.html +++ b/examples/index.html @@ -68,6 +68,7 @@
  • Plotting error bars (with errorbars plugin)
  • Pie charts (with pie plugin)
  • Rendering text with canvas instead of HTML (with canvas plugin)
  • +
  • Adding text into markings.
  • diff --git a/examples/markings/index.html b/examples/markings/index.html new file mode 100644 index 0000000..8ce5a50 --- /dev/null +++ b/examples/markings/index.html @@ -0,0 +1,123 @@ + + + + + Flot Examples: Markings + + + + + + + + + + + + +
    +
    +
    +
    + +

    This example shows how to add text into markings, and how to draw markings with rounded corner.

    +

    The chart here is actually a goal ladder map, and it also shows how to use image plugin to draw icons on to your chart (Notice the "You are here" icon You are here on this chart.). If you don't need to draw images/icons onto your chart, you don't need to reference the image plugin.

    + +
    + + + + + diff --git a/examples/markings/you_are_here.png b/examples/markings/you_are_here.png new file mode 100644 index 0000000000000000000000000000000000000000..a90836c4f573a716b4a39a5e0b884583a78e2c39 GIT binary patch literal 14820 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 xrange.axis.max || - yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) { - continue; - } - - xrange.from = Math.max(xrange.from, xrange.axis.min); - xrange.to = Math.min(xrange.to, xrange.axis.max); - yrange.from = Math.max(yrange.from, yrange.axis.min); - yrange.to = Math.min(yrange.to, yrange.axis.max); - - if (xrange.from === xrange.to && yrange.from === yrange.to) { - continue; - } - - // then draw - xrange.from = xrange.axis.p2c(xrange.from); - xrange.to = xrange.axis.p2c(xrange.to); - yrange.from = yrange.axis.p2c(yrange.from); - yrange.to = yrange.axis.p2c(yrange.to); - - if (xrange.from === xrange.to || yrange.from === yrange.to) { - // draw line - ctx.beginPath(); - ctx.strokeStyle = m.color || options.grid.markingsColor; - ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; - ctx.moveTo(xrange.from, yrange.from); - ctx.lineTo(xrange.to, yrange.to); - ctx.stroke(); + var m = markings[i]; + + if (m.aboveGrid) { + markingsAboveGrid.push(m); } else { - // fill area - ctx.fillStyle = m.color || options.grid.markingsColor; - ctx.fillRect(xrange.from, yrange.to, - xrange.to - xrange.from, - yrange.from - yrange.to); + markingsUnderGrid.push(m); } } } + + drawMarkings(markingsUnderGrid, markingLayer); // draw the ticks axes = allAxes(); @@ -2265,6 +2237,7 @@ Licensed under the MIT license. ctx.stroke(); } + drawMarkings(markingsAboveGrid, markingLayer); // draw border if (bw) { @@ -2323,6 +2296,109 @@ Licensed under the MIT license. ctx.restore(); } + + function drawMarkings(markings, markingLayer) { + if (!markings) { + return; + } + + for (var i = 0; i < markings.length; i++) { + drawMarking(markings[i], markingLayer); + } + } + + function drawMarking(m, markingLayer) { + var xrange = extractRange(m, "x"), + yrange = extractRange(m, "y"); + + // fill in missing + if (xrange.from == null) { + xrange.from = xrange.axis.min; + } + if (xrange.to == null) { + xrange.to = xrange.axis.max; + } + if (yrange.from == null) { + yrange.from = yrange.axis.min; + } + if (yrange.to == null) { + yrange.to = yrange.axis.max; + } + + // clip + if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || + yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) { + return; + } + + xrange.from = Math.max(xrange.from, xrange.axis.min); + xrange.to = Math.min(xrange.to, xrange.axis.max); + yrange.from = Math.max(yrange.from, yrange.axis.min); + yrange.to = Math.min(yrange.to, yrange.axis.max); + + if (xrange.from === xrange.to && yrange.from === yrange.to) { + return; + } + + // then draw + xrange.from = xrange.axis.p2c(xrange.from); + xrange.to = xrange.axis.p2c(xrange.to); + yrange.from = yrange.axis.p2c(yrange.from); + yrange.to = yrange.axis.p2c(yrange.to); + + if (xrange.from === xrange.to || yrange.from === yrange.to) { + // draw line + ctx.beginPath(); + ctx.strokeStyle = m.color || options.grid.markingsColor; + ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; + ctx.moveTo(xrange.from, yrange.from); + ctx.lineTo(xrange.to, yrange.to); + ctx.stroke(); + } else { + // fill area + ctx.fillStyle = m.color || options.grid.markingsColor; + + if (!m.rounded) { + ctx.fillRect(xrange.from, yrange.to, + xrange.to - xrange.from, + yrange.from - yrange.to); + } else { + roundRect(ctx, xrange.from, yrange.to, xrange.to - xrange.from, yrange.from - yrange.to, m.rounded); + ctx.fill(); + } + } + + if (m.text) { + // left aligned horizontal position: + var xPos = xrange.from + plotOffset.left; + // top baselined vertical position: + var yPos = (yrange.to + plotOffset.top); + + if (!!m.textAlign) { + switch (m.textAlign.toLowerCase()) { + case "right": + xPos = xrange.to + plotOffset.left; + break; + case "center": + xPos = (xrange.from + plotOffset.left + xrange.to + plotOffset.left) / 2; + break; + } + } + + if (!!m.textBaseline) { + switch (m.textBaseline.toLowerCase()) { + case "bottom": + yPos = (yrange.from + plotOffset.top); + break; + case "middle": + yPos = (yrange.from + plotOffset.top + yrange.to + plotOffset.top) / 2; + break; + } + } + + surface.addText(markingLayer, xPos, yPos, m.text, m.font || "flot-marking", 0, null, m.textAlign, m.textBaseline); + } + } function drawAxisLabels() { @@ -3405,4 +3481,32 @@ Licensed under the MIT license. return base * Math.floor(n / base); } + // Draw a rectangle with rounded corner on the canvas. + // + // @param {CanvasRenderingContext2D} ctx The canvas 2D context. + // @param {number} x The x-axis coordinate of the upper left corner of + // the rectangle to be drawn. + // @param {number} y The y-axis coordinate of the upper left corner of + // the rectangle to be drawn. + // @param {number} width The width of the rectangle to be drawn. + // @param {number} height The height of the rectangle to be drawn. + // @param {number} radius The radius of the corner of the rectangle + // to be drawn. + function roundRect(ctx, x, y, width, height, radius) { + var r = x + width; + var b = y + height; + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(r - radius, y); + ctx.quadraticCurveTo(r, y, r, y + radius); + ctx.lineTo(r, y + height - radius); + ctx.quadraticCurveTo(r, b, r - radius, b); + ctx.lineTo(x + radius, b); + ctx.quadraticCurveTo(x, b, x, b - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + return ctx; + } + })(jQuery);