Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: third_party/flot/jquery.flot.canvas.js

Issue 1235773002: Add jquery and flot to catapult/third_party. (Closed) Base URL: git@github.com:catapult-project/catapult.git@master
Patch Set: Rebased Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/flot/jquery.flot.js ('k') | third_party/flot/jquery.flot.canvas.min.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Flot plugin for drawing all elements of a plot on the canvas.
2
3 Copyright (c) 2007-2014 IOLA and Ole Laursen.
4 Licensed under the MIT license.
5
6 Flot normally produces certain elements, like axis labels and the legend, using
7 HTML elements. This permits greater interactivity and customization, and often
8 looks better, due to cross-browser canvas text inconsistencies and limitations.
9
10 It can also be desirable to render the plot entirely in canvas, particularly
11 if the goal is to save it as an image, or if Flot is being used in a context
12 where the HTML DOM does not exist, as is the case within Node.js. This plugin
13 switches out Flot's standard drawing operations for canvas-only replacements.
14
15 Currently the plugin supports only axis labels, but it will eventually allow
16 every element of the plot to be rendered directly to canvas.
17
18 The plugin supports these options:
19
20 {
21 canvas: boolean
22 }
23
24 The "canvas" option controls whether full canvas drawing is enabled, making it
25 possible to toggle on and off. This is useful when a plot uses HTML text in the
26 browser, but needs to redraw with canvas text when exporting as an image.
27
28 */
29
30 (function($) {
31
32 var options = {
33 canvas: true
34 };
35
36 var render, getTextInfo, addText;
37
38 // Cache the prototype hasOwnProperty for faster access
39
40 var hasOwnProperty = Object.prototype.hasOwnProperty;
41
42 function init(plot, classes) {
43
44 var Canvas = classes.Canvas;
45
46 // We only want to replace the functions once; the second time a round
47 // we would just get our new function back. This whole replacin g of
48 // prototype functions is a disaster, and needs to be changed AS AP.
49
50 if (render == null) {
51 getTextInfo = Canvas.prototype.getTextInfo,
52 addText = Canvas.prototype.addText,
53 render = Canvas.prototype.render;
54 }
55
56 // Finishes rendering the canvas, including overlaid text
57
58 Canvas.prototype.render = function() {
59
60 if (!plot.getOptions().canvas) {
61 return render.call(this);
62 }
63
64 var context = this.context,
65 cache = this._textCache;
66
67 // For each text layer, render elements marked as active
68
69 context.save();
70 context.textBaseline = "middle";
71
72 for (var layerKey in cache) {
73 if (hasOwnProperty.call(cache, layerKey)) {
74 var layerCache = cache[layerKey];
75 for (var styleKey in layerCache) {
76 if (hasOwnProperty.call(layerCac he, styleKey)) {
77 var styleCache = layerCa che[styleKey],
78 updateStyles = t rue;
79 for (var key in styleCac he) {
80 if (hasOwnProper ty.call(styleCache, key)) {
81
82 var info = styleCache[key],
83 positions = info.positions,
84 lines = info.lines;
85
86 // Since every element at this level of the cache have the
87 // same font and fill styles, we can just change them once
88 // using the values from the first element.
89
90 if (upda teStyles) {
91 context.fillStyle = info.font.color;
92 context.font = info.font.definition;
93 updateStyles = false;
94 }
95
96 for (var i = 0, position; position = positions[i]; i++) {
97 if (position.active) {
98 for (var j = 0, line; line = position.lines[j]; j++) {
99 context.fillText(lines[j].text, line[0], line[1]);
100 }
101 } else {
102 positions.splice(i--, 1);
103 }
104 }
105
106 if (posi tions.length == 0) {
107 delete styleCache[key];
108 }
109 }
110 }
111 }
112 }
113 }
114 }
115
116 context.restore();
117 };
118
119 // Creates (if necessary) and returns a text info object.
120 //
121 // When the canvas option is set, the object looks like this:
122 //
123 // {
124 // width: Width of the text's bounding box.
125 // height: Height of the text's bounding box.
126 // positions: Array of positions at which this text is drawn .
127 // lines: [{
128 // height: Height of this line.
129 // widths: Width of this line.
130 // text: Text on this line.
131 // }],
132 // font: {
133 // definition: Canvas font property string.
134 // color: Color of the text.
135 // },
136 // }
137 //
138 // The positions array contains objects that look like this:
139 //
140 // {
141 // active: Flag indicating whether the text should be visibl e.
142 // lines: Array of [x, y] coordinates at which to draw the l ine.
143 // x: X coordinate at which to draw the text.
144 // y: Y coordinate at which to draw the text.
145 // }
146
147 Canvas.prototype.getTextInfo = function(layer, text, font, angle , width) {
148
149 if (!plot.getOptions().canvas) {
150 return getTextInfo.call(this, layer, text, font, angle, width);
151 }
152
153 var textStyle, layerCache, styleCache, info;
154
155 // Cast the value to a string, in case we were given a n umber
156
157 text = "" + text;
158
159 // If the font is a font-spec object, generate a CSS def inition
160
161 if (typeof font === "object") {
162 textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
163 } else {
164 textStyle = font;
165 }
166
167 // Retrieve (or create) the cache for the text's layer a nd styles
168
169 layerCache = this._textCache[layer];
170
171 if (layerCache == null) {
172 layerCache = this._textCache[layer] = {};
173 }
174
175 styleCache = layerCache[textStyle];
176
177 if (styleCache == null) {
178 styleCache = layerCache[textStyle] = {};
179 }
180
181 info = styleCache[text];
182
183 if (info == null) {
184
185 var context = this.context;
186
187 // If the font was provided as CSS, create a div with those
188 // classes and examine it to generate a canvas f ont spec.
189
190 if (typeof font !== "object") {
191
192 var element = $("<div>&nbsp;</div>")
193 .css("position", "absolute")
194 .addClass(typeof font === "strin g" ? font : null)
195 .appendTo(this.getTextLayer(laye r));
196
197 font = {
198 lineHeight: element.height(),
199 style: element.css("font-style") ,
200 variant: element.css("font-varia nt"),
201 weight: element.css("font-weight "),
202 family: element.css("font-family "),
203 color: element.css("color")
204 };
205
206 // Setting line-height to 1, without uni ts, sets it equal
207 // to the font-size, even if the font-si ze is abstract,
208 // like 'smaller'. This enables us to r ead the real size
209 // via the element's height, working aro und browsers that
210 // return the literal 'smaller' value.
211
212 font.size = element.css("line-height", 1 ).height();
213
214 element.remove();
215 }
216
217 textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
218
219 // Create a new info object, initializing the di mensions to
220 // zero so we can count them up line-by-line.
221
222 info = styleCache[text] = {
223 width: 0,
224 height: 0,
225 positions: [],
226 lines: [],
227 font: {
228 definition: textStyle,
229 color: font.color
230 }
231 };
232
233 context.save();
234 context.font = textStyle;
235
236 // Canvas can't handle multi-line strings; break on various
237 // newlines, including HTML brs, to build a list of lines.
238 // Note that we could split directly on regexps, but IE < 9 is
239 // broken; revisit when we drop IE 7/8 support.
240
241 var lines = (text + "").replace(/<br ?\/?>|\r\n| \r/g, "\n").split("\n");
242
243 for (var i = 0; i < lines.length; ++i) {
244
245 var lineText = lines[i],
246 measured = context.measureText(l ineText);
247
248 info.width = Math.max(measured.width, in fo.width);
249 info.height += font.lineHeight;
250
251 info.lines.push({
252 text: lineText,
253 width: measured.width,
254 height: font.lineHeight
255 });
256 }
257
258 context.restore();
259 }
260
261 return info;
262 };
263
264 // Adds a text string to the canvas text overlay.
265
266 Canvas.prototype.addText = function(layer, x, y, text, font, ang le, width, halign, valign) {
267
268 if (!plot.getOptions().canvas) {
269 return addText.call(this, layer, x, y, text, fon t, angle, width, halign, valign);
270 }
271
272 var info = this.getTextInfo(layer, text, font, angle, wi dth),
273 positions = info.positions,
274 lines = info.lines;
275
276 // Text is drawn with baseline 'middle', which we need t o account
277 // for by adding half a line's height to the y position.
278
279 y += info.height / lines.length / 2;
280
281 // Tweak the initial y-position to match vertical alignm ent
282
283 if (valign == "middle") {
284 y = Math.round(y - info.height / 2);
285 } else if (valign == "bottom") {
286 y = Math.round(y - info.height);
287 } else {
288 y = Math.round(y);
289 }
290
291 // FIXME: LEGACY BROWSER FIX
292 // AFFECTS: Opera < 12.00
293
294 // Offset the y coordinate, since Opera is off pretty
295 // consistently compared to the other browsers.
296
297 if (!!(window.opera && window.opera.version().split(".") [0] < 12)) {
298 y -= 2;
299 }
300
301 // Determine whether this text already exists at this po sition.
302 // If so, mark it for inclusion in the next render pass.
303
304 for (var i = 0, position; position = positions[i]; i++) {
305 if (position.x == x && position.y == y) {
306 position.active = true;
307 return;
308 }
309 }
310
311 // If the text doesn't exist at this position, create a new entry
312
313 position = {
314 active: true,
315 lines: [],
316 x: x,
317 y: y
318 };
319
320 positions.push(position);
321
322 // Fill in the x & y positions of each line, adjusting t hem
323 // individually for horizontal alignment.
324
325 for (var i = 0, line; line = lines[i]; i++) {
326 if (halign == "center") {
327 position.lines.push([Math.round(x - line .width / 2), y]);
328 } else if (halign == "right") {
329 position.lines.push([Math.round(x - line .width), y]);
330 } else {
331 position.lines.push([Math.round(x), y]);
332 }
333 y += line.height;
334 }
335 };
336 }
337
338 $.plot.plugins.push({
339 init: init,
340 options: options,
341 name: "canvas",
342 version: "1.0"
343 });
344
345 })(jQuery);
OLDNEW
« no previous file with comments | « third_party/flot/jquery.flot.js ('k') | third_party/flot/jquery.flot.canvas.min.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698