1/*----------------------------------------------------------------------*/ 2/* wl_Chart v 1.0 by revaxarts.com 3/* description: extends the flot library 4/* dependency: flot library 5/*----------------------------------------------------------------------*/ 6$.fn.wl_Chart = function (method) { 7 8 var args = arguments; 9 return this.each(function () { 10 11 var $this = $(this); 12 13 14 if ($.fn.wl_Chart.methods[method]) { 15 return $.fn.wl_Chart.methods[method].apply(this, Array.prototype.slice.call(args, 1)); 16 } else if (typeof method === 'object' || !method) { 17 if ($this.data('wl_Chart')) { 18 var opts = $.extend({}, $this.data('wl_Chart'), method); 19 } else { 20 var opts = $.extend({}, $.fn.wl_Chart.defaults, method, $this.data()); 21 } 22 } else { 23 try { 24 return $this.data('wl_Chart').plot[method](args[1], args[2]); 25 } catch (e) { 26 $.error('Method "' + method + '" does not exist'); 27 } 28 } 29 30 //throw an error if wrong chart typ is set 31 if (!/^(lines|bars|pie)$/.test(opts.type)) { 32 $.error('Type of "' + opts.type + '" is not allowed'); 33 } 34 35 if (!$this.data('wl_Chart')) { 36 37 $this.data('wl_Chart', {}); 38 39 //bind a resize event to redraw the chart if the window size change 40 $(window).bind('resize.wl_Chart', function () { 41 $this.data('wl_Chart').holder.width('99%'); 42 $.fn.wl_Chart.methods.draw.call($this[0]); 43 }); 44 45 //make a holder for the chart and set the width too 99% (100% causes overflow problems in some browsers) 46 opts.holder = $('<div/>', { 47 'class': 'chart' 48 }).css({ 49 width: (opts.width || $this.width() || '100%') / 100 * 99, 50 height: opts.height || 300 51 }).insertAfter($this); 52 53 54 } else { 55 56 //quick destroy 57 opts.holder.unbind("plothover").unbind('mouseout'); 58 59 } 60 61 62 63 //set the width 64 opts.width = opts.holder.width(); 65 66 //show or hide the table 67 (opts.hideTable) ? $this.hide() : $this.show(); 68 69 70 //bind the click event on the stats 71 opts.holder.bind("plotclick", function (event, pos, item) { 72 if (item) { 73 var patt = {}; 74 switch (opts.type) { 75 case 'bars': 76 patt['value'] = item.datapoint[1]; 77 patt['label'] = item.series.xaxis.ticks[item.dataIndex].label; 78 patt['id'] = item.seriesIndex; 79 break; 80 case 'pie': 81 patt['value'] = item.datapoint[1][0][1]; 82 patt['label'] = item.series.xaxis.options.ticks[0][1]; 83 patt['id'] = item.seriesIndex; 84 break; 85 default: 86 patt['value'] = item.datapoint[1]; 87 patt['label'] = item.series.xaxis.ticks[item.datapoint[0]].label; 88 patt['id'] = item.seriesIndex; 89 90 } 91 patt['legend'] = item.series.label; 92 opts.onClick.call($this[0], patt['value'], patt['legend'], patt['label'], patt['id']); 93 } 94 }); 95 96 //We have a tooltip 97 if (opts.tooltip) { 98 99 //attach the tipsy tooltip to the holder 100 opts.holder.tipsy($.extend({}, config.tooltip, { 101 fallback: '', 102 followMouse: true, 103 gravity: opts.tooltipGravity || 'n' 104 })); 105 106 107 var prev = null, 108 text; 109 110 //bind a hover event to the graph 111 opts.holder.bind("plothover", function (e, pos, item) { 112 if (item) { 113 114 //check if we don't have to do the same stuff more then once 115 if (item.datapoint.toString() != prev) { 116 var patt = {}; 117 prev = item.datapoint.toString(); 118 119 120 switch (opts.type) { 121 case 'bars': 122 patt['value'] = item.datapoint[1]; 123 patt['label'] = item.series.xaxis.ticks[item.dataIndex].label; 124 patt['id'] = item.seriesIndex; 125 break; 126 case 'pie': 127 patt['value'] = item.datapoint[1][0][1]; 128 patt['label'] = item.series.xaxis.options.ticks[0][1]; 129 patt['id'] = item.seriesIndex; 130 break; 131 default: 132 patt['value'] = item.datapoint[1]; 133 patt['label'] = item.series.xaxis.ticks[item.datapoint[0]].label; 134 patt['id'] = item.seriesIndex; 135 136 } 137 patt['legend'] = item.series.label; 138 139 //is the pattern a function or a simple string? 140 if ($.isFunction(opts.tooltipPattern)) { 141 text = opts.tooltipPattern.call($this[0], patt['value'], patt['legend'], patt['label'], patt['id']); 142 } else { 143 text = opts.tooltipPattern.replace(/%1/g, patt['value']).replace(/%2/g, patt['legend']).replace(/%3/g, patt['label']).replace(/%4/g, patt['id']); 144 } 145 //set the title and show the tooltip 146 opts.holder.tipsy('setTitel', text); 147 opts.holder.tipsy('show'); 148 149 } else { 150 return; 151 } 152 153 } else { 154 //hide tooltip if we leave the point 155 opts.holder.tipsy('hide'); 156 prev = null; 157 } 158 }).bind('mouseout', function () { 159 160 //hide tooltip if we leave the plot 161 opts.holder.tipsy('hide'); 162 prev = null; 163 }); 164 165 } 166 167 168 //the colors are maybe not an array if they a specified within a data attribute 169 if (!$.isArray(opts.colors)) { 170 opts.colors = $.parseData(opts.colors, true); 171 } 172 173 var colors = []; 174 175 //a data object is set (no table) 176 if (!$.isEmptyObject(opts.data)) { 177 178 //labels on the x axis are set 179 if (opts.xlabels) { 180 181 //convert them in the proper format 182 opts.xlabels = $.map(opts.xlabels, function (value, key) { 183 return [[key, value]]; 184 }); 185 186 //no labels are set 187 } else { 188 189 //get labels out of the data 190 opts.xlabels = function () { 191 var ret = []; 192 $.each(opts.data, function (i, e) { 193 $.map(opts.data[i].data, function (value, key) { 194 ret[value[0]] = key; 195 }); 196 }); 197 return $.map(ret, function (value, key) { 198 return key; 199 }); 200 }(); 201 202 } 203 204 //define colors in a loop 205 colors = $.map(opts.data, function (value, key) {
206 return opts.colors[key % opts.colors.length]; 207 }); 208 209 //data is from a table 210 } else if ($.isEmptyObject(opts.data) && $this.is('table')) { 211 212 opts.xlabels = opts.xlabels || []; 213 opts.data = []; 214 215 switch (opts.orientation) { 216 217 218 //table is in horizontal mode (normal) 219 case 'horizontal': 220 221 var $xlabels = $this.find('thead th'), 222 $legends = $this.find('tbody th'), 223 $rows = $this.find('tbody tr'); 224 225 var legendlength = $legends.length; 226 227 //strip the very first cell because it's not necessary 228 if (legendlength) $xlabels = $xlabels.slice(1); 229 230 //fetch each row of the table 231 $rows.each(function (i, row) { 232 var data = $(row).find('td'), 233 _d = []; 234 235 //fetch each cell of the row 236 data.each(function (j, td) { 237 var d = parseInt(td.innerHTML); 238 239 //only numbers are valid 240 if (!isNaN(d)) _d.push([j, (d || 0)]); 241 242 //some stuff for the labels on the x axis 243 opts.xlabels.push([j, $xlabels.eq(j).text()]); 244 }); 245 246 //push the data in the data-object for this row (label) 247 opts.data.push({ 248 'label': $legends.eq(i).text(), 249 'data': (opts.type != 'pie') ? _d : _d[0][1] 250 }); 251 252 //define colors in a loop 253 colors[i] = $rows.eq(i).data('color') || opts.colors[i] || colors[i % opts.colors.length]; 254 }); 255 break; 256 257 258 //table is in vertical mode 259 case 'vertical': 260 261 var $xlabels = $this.find('tbody th'), 262 $legends = $this.find('thead th'), 263 $rows = $this.find('tbody tr'); 264 265 var legendlength = $legends.length; 266 267 if (legendlength) { 268 $legends = $legends.slice(1); 269 legendlength--; 270 } 271 272 var _d = []; 273 274 //fetch each row of the table 275 $rows.each(function (i, row) { 276 var data = $(row).find('td'); 277 data.each(function (j, td) { 278 var d = parseInt(td.innerHTML); 279 _d[j] = _d[j] || []; 280 281 //only numbers are valid 282 if (!isNaN(d)) _d[j].push([i, (d || 0)]); 283 284 }); 285 286 //some stuff for the labels on the x axis 287 opts.xlabels.push([i, $xlabels.eq(i).text()]); 288 289 }); 290 291 //push the data in the data-object for this row (label) and define the colors 292 for (var i = 0; i < legendlength; i++) { 293 opts.data.push({ 294 'label': $legends.eq(i).text(), 295 'data': _d[i] 296 }); 297 colors[i] = opts.colors[i] || colors[i % opts.colors.length]; 298 } 299 300 break; 301 302 default: 303 //trigger an error 304 $.error('Orientation "' + opts.orientation + '" is not allowed'); 305 306 307 } 308 309 } else { 310 311 //trigger an error id no data or ttable is set 312 $.error('No data or data table!'); 313 314 } 315 316 317 opts.colors = colors; 318 var std = {}; 319 320 //define some chart type specific standards 321 switch (opts.type) { 322 case 'bars': 323 std = { 324 points: { 325 show: (opts.points !== null) ? opts.points : false 326 }, 327 bars: { 328 order: (opts.stack) ? null : true, 329 show: true, 330 border: false, 331 fill: (opts.fill !== null) ? opts.fill : true, 332 fillColor: (opts.fillColor !== null) ? opts.fillColor : null, 333 align: opts.align || 'center', 334 horizontal: opts.horizontal || false, 335 barWidth: opts.barWidth || (opts.stack) ? 0.85 : 0.85 / opts.data.length, 336 lineWidth: (opts.lineWidth !== null) ? opts.lineWidth : 0 337 }, 338 lines: { 339 show: false 340 }, 341 pie: { 342 show: false 343 } 344 }; 345 break; 346 case 'pie': 347 std = { 348 points: { 349 show: (opts.points !== null) ? opts.points : true 350 }, 351 bars: { 352 show: false 353 }, 354 lines: { 355 show: false 356 }, 357 pie: { 358 show: true, 359 label: true, 360 tilt: opts.tilt || 1, 361 innerRadius: (opts.innerRadius) ? opts.innerRadius : 0, 362 radius: (opts.tilt && !opts.radius) ? 0.8 : opts.radius || 1, 363 shadowSize: 2 364 } 365 }; 366 break; 367 case 'lines': 368 default: 369 std = { 370 points: { 371 show: (opts.points !== null) ? opts.points : true 372 }, 373 bars: { 374 show: false 375 }, 376 lines: { 377 show: true, 378 lineWidth: (opts.lineWidth !== null) ? opts.lineWidth : 4, 379 fill: (opts.fill !== null) ? opts.fill : false, 380 fillColor: (opts.fillColor !== null) ? opts.fillColor : null 381 }, 382 pie: { 383 show: false 384 } 385 }; 386 } 387 388 389 //some more standards and maybe the flot object 390 var options = $.extend(true, {}, { 391 392 series: $.extend(true, {}, { 393 //must set to null not to false 394 stack: (opts.stack) ? true : null, 395 points: { 396 show: opts.points 397 } 398 }, std), 399 400 shadowSize: opts.shadowSize || 0, 401 402 grid: { 403 hoverable: opts.tooltip, 404 clickable: true, 405 color: '#666', 406 borderWidth: null 407 }, 408 409 legend: { 410 show: opts.legend, 411 position: (/^(ne|nw|se|sw)$/.test(opts.legendPosition)) ? opts.legendPosition : '
411ne' 412 }, 413 colors: opts.colors, 414 xaxis: { 415 ticks: opts.xlabels 416 } 417 }, opts.flot); 418 419 //extend the flot object 420 opts.flotobj = $.extend({}, opts.flotobj, options); 421 422 if (opts) $.extend($this.data('wl_Chart'), opts); 423 424 //let's draw the graph 425 $.fn.wl_Chart.methods.draw.call(this); 426 }); 427 428}; 429 430$.fn.wl_Chart.defaults = { 431 width: null, 432 height: 300, 433 hideTable: true, 434 data: {}, 435 stack: false, 436 type: 'lines', 437 points: null, 438 shadowSize: 2, 439 fill: null, 440 fillColor: null, 441 lineWidth: null, 442 legend: true, 443 legendPosition: "nw", // or "ne" or "se" or "sw" 444 tooltip: true, 445 tooltipGravity: 'n', 446 tooltipPattern: function (value, legend, label, id) { 447 return "value is " + value + " from " + legend + " at " + label + " (" + id + ")"; 448 }, 449 orientation: 'horizontal', 450 colors: ['#b2e7b2', '#f0b7b7', '#b5f0f0', '#e8e8b3', '#efb7ef', '#bbb6f0'], 451 flot: {}, 452 onClick: function (value, legend, label, id) {} 453}; 454 455$.fn.wl_Chart.version = '1.0'; 456 457 458$.fn.wl_Chart.methods = { 459 draw: function () { 460 var $this = $(this), 461 _opts = $this.data('wl_Chart'); 462 //draw the chart and save it within the DOM 463 $this.data('wl_Chart').plot = $.plot(_opts.holder, _opts.data, _opts.flotobj); 464 }, 465 set: function () { 466 var $this = $(this), 467 options = {}; 468 if (typeof arguments[0] === 'object') { 469 options = arguments[0]; 470 } else if (arguments[0] && arguments[1] !== undefined) { 471 options[arguments[0]] = arguments[1]; 472 } 473 $.each(options, function (key, value) { 474 if ($.fn.wl_Chart.defaults[key] !== undefined || $.fn.wl_Chart.defaults[key] == null) { 475 $this.data('wl_Chart')[key] = value; 476 } else { 477 $.error('Key "' + key + '" is not defined'); 478 } 479 }); 480 481 } 482};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.