- 浏览: 103385 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
Tom.X:
http://osgia.com
OSGI下的web应用开发(5) -
xiaohei520104:
楼组辛苦了,关于OSGi web的demo资料很少,非常感谢你 ...
OSGI下的web应用开发(5) -
shenwu33:
为什么我的server下面 没有eclipseRT
OSGI下的web应用开发(1) -
zhaoweisgz:
谢谢你的共享~
基于virgo环境的OSGI+Maven的web开发代码下载(spring+hibernate+GWT) -
zrz_1989:
楼主我想请教您个问题,如果将项目移植到OSGi平台上,对于we ...
OSGI下的web应用开发(7)
由于项目中需要使用到speedo meter chart,但是又不能使用flash(因为要支持iphone),而speedo的js插件网上貌似很难找到,找到了一个但是却不是很满意,因为没办法灵活的定义UI(如果有需要链接在这里http://plugins.jquery.com/project/speedometer),因为实现起来不是很复杂,而且刚好的flot插件中也有一个pie的plugin,想了一下通过修改这个plugin来实现的话就可以了,下面给出这个代码的api定义:
// 这里的API是flot相关的,具体还需参见flot的API定义
series: {
meter:{ // 定义了一个meter object,所有的参数定义都在这里 show: true, // 是否显示该chart label: { // 是否显示各个段的百分比及名称 show: false },
radius: 1, // 圆的半径定义,数值是0-1,是一个比例值,基数是整个chart的宽度的一半,默认是1
innerRadius: 0.5, // 内圆的半径定义,也就是空白部分的范围,通过它来调整遮罩范围,也是一个比例值,同上,默认是0.5
currentValue: 0, // 当前此chart对应指针指定的数值,如果没有默认是0
pointerLength: 0.75, // 指针长度,是一个比例值,基数是radius的长度,默认是0.75
maxScale: 100, // 当前chart反应的最大值标量,如果没有输入默认显示100%,接受一个浮点型的数
title: 'the speedo chart' // chart的title,默认是speedo chart }
}
你还可以为chart所对应的div做css定义,这样的话就可以有不同的边框和背景了,可以根据你的网站样式作出不同的调整,而meter的颜色定义则还是由flot的定义给出,这里不做修改
下面贴出整个插件的源码:
(function ($) { function init(plot) // this is the "body" of the plugin { var canvas = null; var target = null; var maxRadius = null; var currentRadius = null; var centerLeft = null; var centerTop = null; var total = 0; var redraw = true; var redrawAttempts = 10; var shrink = 0.95; var legendWidth = 0; var processed = false; var raw = false; // interactive variables var highlights = []; // add hook to determine if meter plugin in enabled, and then perform necessary operations plot.hooks.processOptions.push(checkPieEnabled); plot.hooks.bindEvents.push(bindEvents); // check to see if the meter plugin is enabled function checkPieEnabled(plot, options) { if (options.series.meter.show) { //disable grid options.grid.show = false; // set labels.show if (options.series.meter.label.show=='auto') if (options.legend.show) options.series.meter.label.show = false; else options.series.meter.label.show = true; // set radius if (options.series.meter.radius=='auto') if (options.series.meter.label.show) options.series.meter.radius = 3/4; else options.series.meter.radius = 1; if(!options.series.meter.innerRadius) options.series.meter.innerRadius = options.series.meter.radius/2; if (!options.series.meter.title) options.series.meter.title = "Meter Chart"; if(!options.series.meter.currentValue) options.series.meter.currentValue = 0; if(!options.series.meter.pointerLength) options.series.meter.pointerLength = options.series.meter.radius*3/4; // ensure sane tilt if (options.series.meter.tilt>1) options.series.meter.tilt=1; if (options.series.meter.tilt<0) options.series.meter.tilt=0; if (!options.series.meter.maxScale) options.series.meter.maxScale="100%"; // treate as percentage value options.series.meter.startAngle = 1; // add processData hook to do transformations on the data plot.hooks.processDatapoints.push(processDatapoints); plot.hooks.drawOverlay.push(drawOverlay); // add draw hook plot.hooks.draw.push(draw); } } // bind hoverable events function bindEvents(plot, eventHolder) { var options = plot.getOptions(); if (options.series.meter.show && options.grid.hoverable) eventHolder.unbind('mousemove').mousemove(onMouseMove); if (options.series.meter.show && options.grid.clickable) eventHolder.unbind('click').click(onClick); } // debugging function that prints out an object function alertObject(obj) { var msg = ''; function traverse(obj, depth) { if (!depth) depth = 0; for (var i = 0; i < obj.length; ++i) { for (var j=0; j<depth; j++) msg += '\t'; if( typeof obj[i] == "object") { // its an object msg += ''+i+':\n'; traverse(obj[i], depth+1); } else { // its a value msg += ''+i+': '+obj[i]+'\n'; } } } traverse(obj); alert(msg); } function calcTotal(data) { for (var i = 0; i < data.length; ++i) { var item = parseFloat(data[i].data[0][1]); if (item) total += item; } } function processDatapoints(plot, series, data, datapoints) { if (!processed) { processed = true; canvas = plot.getCanvas(); target = $(canvas).parent(); options = plot.getOptions(); plot.setData(combine(plot.getData())); } } function setupPie() { legendWidth = target.children().filter('.legend').children().width(); // calculate maximum radius and center point maxRadius = canvas.width/2; centerTop = (canvas.height)+options.series.meter.offset.top; centerLeft = (canvas.width/2); if (options.series.meter.offset.left=='auto') if (options.legend.position.match('w')) centerLeft += legendWidth/2; else centerLeft -= legendWidth/2; else centerLeft += options.series.meter.offset.left; if (centerLeft<maxRadius) centerLeft = maxRadius; else if (centerLeft>canvas.width-maxRadius) centerLeft = canvas.width-maxRadius; } function fixData(data) { for (var i = 0; i < data.length; ++i) { if (typeof(data[i].data)=='number') data[i].data = [[1,data[i].data]]; else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined') { if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined') data[i].label = data[i].data.label; // fix weirdness coming from flot data[i].data = [[1,0]]; } } return data; } function combine(data) { data = fixData(data); calcTotal(data); var combined = 0; var numCombined = 0; var color = options.series.meter.combine.color; var newdata = []; for (var i = 0; i < data.length; ++i) { // make sure its a number data[i].data[0][1] = parseFloat(data[i].data[0][1]); if (!data[i].data[0][1]) data[i].data[0][1] = 0; if (data[i].data[0][1]/total<=options.series.meter.combine.threshold) { combined += data[i].data[0][1]; numCombined++; if (!color) color = data[i].color; } else { newdata.push({ data: [[1,data[i].data[0][1]]], color: data[i].color, label: data[i].label, angle: (data[i].data[0][1]*(Math.PI))/total, percent: (data[i].data[0][1]/total*100) }); } } if (numCombined>0) newdata.push({ data: [[1,combined]], color: color, label: options.series.meter.combine.label, angle: (combined*(Math.PI))/total, percent: (combined/total*100) }); return newdata; } function draw(plot, newCtx) { if (!target) return; // if no series were passed ctx = newCtx; setupPie(); var slices = plot.getData(); var attempts = 0; while (redraw && attempts<redrawAttempts) { redraw = false; if (attempts>0) maxRadius *= shrink; attempts += 1; clear(); if (options.series.meter.tilt<=0.8) drawShadow(); drawPie(); } if (attempts >= redrawAttempts) { clear(); target.prepend('<div class="error">Could not draw meter with labels contained inside canvas</div>'); } if ( plot.setSeries && plot.insertLegend ) { plot.setSeries(slices); plot.insertLegend(); } // we're actually done at this point, just defining internal functions at this point function clear() { ctx.clearRect(0,0,canvas.width,canvas.height); target.children().filter('.pieLabel, .pieLabelBackground').remove(); } function drawShadow() { var shadowLeft = 5; var shadowTop = 15; var edge = 10; var alpha = 0.02; // set radius if (options.series.meter.radius>1) var radius = options.series.meter.radius; else var radius = maxRadius * options.series.meter.radius; if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.meter.tilt>=(canvas.height/2)-shadowTop || radius<=edge) return; // shadow would be outside canvas, so don't draw it ctx.save(); ctx.translate(shadowLeft,shadowTop); ctx.globalAlpha = alpha; ctx.fillStyle = '#000'; // center and rotate to starting position ctx.translate(centerLeft,centerTop); ctx.scale(1, options.series.meter.tilt); //radius -= edge; for (var i=1; i<=edge; i++) { ctx.beginPath(); ctx.arc(0,0,radius,0,Math.PI,false); ctx.fill(); radius -= i; } ctx.restore(); } function drawPie() { startAngle = Math.PI*options.series.meter.startAngle; // set radius if (options.series.meter.radius>1) var radius = options.series.meter.radius; else var radius = maxRadius * options.series.meter.radius; // center and rotate to starting position ctx.save(); ctx.translate(centerLeft,centerTop); ctx.scale(1, options.series.meter.tilt); //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera // draw slices ctx.save(); var currentAngle = startAngle; for (var i = 0; i < slices.length; ++i) { slices[i].startAngle = currentAngle; drawSlice(slices[i].angle, slices[i].color, true); } ctx.restore(); // draw slice outlines ctx.save(); ctx.lineWidth = options.series.meter.stroke.width; currentAngle = startAngle; for (var i = 0; i < slices.length; ++i) drawSlice(slices[i].angle, options.series.meter.stroke.color, false); ctx.restore(); // draw donut hole drawDonutHole(ctx); // draw labels if (options.series.meter.label.show) drawLabels(); printTitle(); // restore to original state ctx.restore(); // print scale printScaleText(); // draw pointer drawPointer(); // print current scale printCurentScaleValue(); function drawSlice(angle, color, fill) { if (angle<=0) return; if (fill) ctx.fillStyle = color; else { ctx.strokeStyle = color; ctx.lineJoin = 'round'; } ctx.beginPath(); if (Math.abs(angle - Math.PI) > 0.000000001) ctx.moveTo(0,0); // Center of the meter else if ($.browser.msie) angle -= 0.0001; //ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false); ctx.closePath(); //ctx.rotate(angle); // This doesn't work properly in Opera currentAngle += angle; if (fill) ctx.fill(); else ctx.stroke(); } function drawLabels() { var currentAngle = startAngle; // set radius if (options.series.meter.label.radius>1) var radius = options.series.meter.label.radius; else var radius = maxRadius * options.series.meter.label.radius; for (var i = 0; i < slices.length; ++i) { if (slices[i].percent >= options.series.meter.label.threshold*100) drawLabel(slices[i], currentAngle, i); currentAngle += slices[i].angle; } function drawLabel(slice, startAngle, index) { if (slice.data[0][1]==0) return; // format label text var lf = options.legend.labelFormatter, text, plf = options.series.meter.label.formatter; if (lf) text = lf(slice.label, slice); else text = slice.label; if (plf) text = plf(text, slice); var halfAngle = ((startAngle+slice.angle) + startAngle)/2; var x = centerLeft + Math.round(Math.cos(halfAngle) * radius); var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.meter.tilt; var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>"; target.append(html); var label = target.children('#pieLabel'+index); var labelTop = (y - label.height()/2); var labelLeft = (x - label.width()/2); label.css('top', labelTop); label.css('left', labelLeft); // check to make sure that the label is not outside the canvas if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0) redraw = true; if (options.series.meter.label.background.opacity != 0) { // put in the transparent background separately to avoid blended labels and label boxes var c = options.series.meter.label.background.color; if (c == null) { c = slice.color; } var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;'; $('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.meter.label.background.opacity); } } // end individual label function } // end drawLabels function function printTitle() { var html = "<span class='MeterChart_Title' style='font-size:12px; position:absolute; top:10px;'>"+options.series.meter.title+"</span>"; $(html).appendTo(target).css("left", (centerLeft-(options.series.meter.title+"").length*getFontSize(html)/4)+"px"); } // end printTitle function function printScaleText() { var radius = options.series.meter.radius*maxRadius; var innerRadius = options.series.meter.innerRadius*maxRadius; // print min scale var minScaleHTML = "<span style='font-weight: bold; position:absolute; top:"+centerTop+"px; left: "+(radius-innerRadius)/2*0.9+"px;'>0</span>"; target.append(minScaleHTML); var maxScaleHTML = "<span style='font-weight: bold; position:absolute; top:"+centerTop+"px; left: "+(radius+innerRadius+(radius-innerRadius)/2)*0.95+"px;'>"+options.series.meter.maxScale+"</span>"; target.append(maxScaleHTML); } // end printScale function function drawPointer() { var value = options.series.meter.currentValue; var pointerLength = options.series.meter.pointerLength * maxRadius; var maxScale = parseFloat(options.series.meter.maxScale); var angle = Math.PI*value/maxScale; var pointerWidth = 6; var startX = centerLeft - Math.floor(pointerLength*Math.cos(angle))-1; var startY = centerTop - Math.floor(pointerLength*Math.sin(angle))-1; ctx.beginPath(); ctx.moveTo(startX,startY); ctx.lineTo(centerLeft+pointerWidth/2*Math.sin(angle),centerTop-pointerWidth/2*Math.cos(angle)); ctx.lineTo(centerLeft-pointerWidth/2*Math.sin(angle),centerTop+pointerWidth/2*Math.cos(angle)); ctx.fill(); } // end drawPointer function function printCurentScaleValue() { var html = "<div class='MeterChart_Value' style='font-size: 16px; position:absolute; top:"+(centerTop+10)+"px;'>"+options.series.meter.currentValue+"</div>"; $(html).appendTo(target).css("left", (centerLeft-(options.series.meter.currentValue+"").length*getFontSize(html)/4)+"px"); } // end printCurentScaleValue function function getFontSize(html) { var fontSize = $(html).css("fontSize"); if(fontSize.indexOf("px") > -1) { fontSize = parseInt(fontSize); } else if(fontSize.indexOf("em") > -1) { fontSize = Math.floor(parseFloat(fontSize)*16); } else if(fontSize.indexOf("pt") > -1) { fontSize = Math.floor(parseFloat(fontSize)*4/3); } else { fontSize = centerLeft; } return fontSize; } } // end drawPie function } // end draw function // Placed here because it needs to be accessed from multiple locations function drawDonutHole(layer) { // draw donut hole if(options.series.meter.innerRadius > 0) { // subtract the center layer.save(); innerRadius = options.series.meter.innerRadius > 1 ? options.series.meter.innerRadius : maxRadius * options.series.meter.innerRadius; layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color layer.beginPath(); layer.fillStyle = options.series.meter.stroke.color; layer.arc(0,0,innerRadius,0,Math.PI*2,false); layer.fill(); layer.closePath(); layer.restore(); // add inner stroke layer.save(); layer.beginPath(); layer.strokeStyle = options.series.meter.stroke.color; layer.arc(0,0,innerRadius,0,Math.PI*2,false); layer.stroke(); layer.closePath(); layer.restore(); // TODO: add extra shadow inside hole (with a mask) if the meter is tilted. } } //-- Additional Interactive related functions -- function isPointInPoly(poly, pt) { for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1])) && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) && (c = !c); return c; } function findNearbySlice(mouseX, mouseY) { var slices = plot.getData(), options = plot.getOptions(), radius = options.series.meter.radius > 1 ? options.series.meter.radius : maxRadius * options.series.meter.radius; for (var i = 0; i < slices.length; ++i) { var s = slices[i]; if(s.meter.show) { ctx.save(); ctx.beginPath(); ctx.moveTo(0,0); // Center of the meter //ctx.scale(1, options.series.meter.tilt); // this actually seems to break everything when here. ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false); ctx.closePath(); x = mouseX-centerLeft; y = mouseY-centerTop; if(ctx.isPointInPath) { if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop)) { //alert('found slice!'); ctx.restore(); return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i}; } } else { // excanvas for IE doesn;t support isPointInPath, this is a workaround. p1X = (radius * Math.cos(s.startAngle)); p1Y = (radius * Math.sin(s.startAngle)); p2X = (radius * Math.cos(s.startAngle+(s.angle/4))); p2Y = (radius * Math.sin(s.startAngle+(s.angle/4))); p3X = (radius * Math.cos(s.startAngle+(s.angle/2))); p3Y = (radius * Math.sin(s.startAngle+(s.angle/2))); p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5))); p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5))); p5X = (radius * Math.cos(s.startAngle+s.angle)); p5Y = (radius * Math.sin(s.startAngle+s.angle)); arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]]; arrPoint = [x,y]; // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for meter tilt? if(isPointInPoly(arrPoly, arrPoint)) { ctx.restore(); return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i}; } } ctx.restore(); } } return null; } function onMouseMove(e) { triggerClickHoverEvent('plothover', e); } function onClick(e) { triggerClickHoverEvent('plotclick', e); } // trigger click or hover event (they send the same parameters so we share their code) function triggerClickHoverEvent(eventname, e) { var offset = plot.offset(), canvasX = parseInt(e.pageX - offset.left), canvasY = parseInt(e.pageY - offset.top), item = findNearbySlice(canvasX, canvasY); if (options.grid.autoHighlight) { // clear auto-highlights for (var i = 0; i < highlights.length; ++i) { var h = highlights[i]; if (h.auto == eventname && !(item && h.series == item.series)) unhighlight(h.series); } } // highlight the slice if (item) highlight(item.series, eventname); // trigger any hover bind events var pos = { pageX: e.pageX, pageY: e.pageY }; target.trigger(eventname, [ pos, item ]); } function highlight(s, auto) { if (typeof s == "number") s = series[s]; var i = indexOfHighlight(s); if (i == -1) { highlights.push({ series: s, auto: auto }); plot.triggerRedrawOverlay(); } else if (!auto) highlights[i].auto = false; } function unhighlight(s) { if (s == null) { highlights = []; plot.triggerRedrawOverlay(); } if (typeof s == "number") s = series[s]; var i = indexOfHighlight(s); if (i != -1) { highlights.splice(i, 1); plot.triggerRedrawOverlay(); } } function indexOfHighlight(s) { for (var i = 0; i < highlights.length; ++i) { var h = highlights[i]; if (h.series == s) return i; } return -1; } function drawOverlay(plot, octx) { //alert(options.series.meter.radius); var options = plot.getOptions(); //alert(options.series.meter.radius); var radius = options.series.meter.radius > 1 ? options.series.meter.radius : maxRadius * options.series.meter.radius; octx.save(); octx.translate(centerLeft, centerTop); octx.scale(1, options.series.meter.tilt); for (i = 0; i < highlights.length; ++i) drawHighlight(highlights[i].series); drawDonutHole(octx); octx.restore(); function drawHighlight(series) { if (series.angle < 0) return; //octx.fillStyle = parseColor(options.series.meter.highlight.color).scale(null, null, null, options.series.meter.highlight.opacity).toString(); octx.fillStyle = "rgba(255, 255, 255, "+options.series.meter.highlight.opacity+")"; // this is temporary until we have access to parseColor octx.beginPath(); if (Math.abs(series.angle - Math.PI) > 0.000000001) octx.moveTo(0,0); // Center of the meter octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false); octx.closePath(); octx.fill(); } } } // end init (plugin body) // define meter specific options and their default values var options = { series: { meter: { show: false, radius: 'auto', // actual radius of the visible meter (based on full calculated radius if <=1, or hard pixel value) innerRadius:0, /* for donut */ startAngle: 3/2, tilt: 1, offset: { top: 0, left: 'auto' }, stroke: { color: '#FFF', width: 1 }, label: { show: 'auto', formatter: function(label, slice){ return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>'; }, // formatter function radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value) background: { color: null, opacity: 0 }, threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow) }, combine: { threshold: -1, // percentage at which to combine little slices into one larger slice color: null, // color to give the new slice (auto-generated if null) label: 'Other' // label to give the new slice }, highlight: { //color: '#FFF', // will add this functionality once parseColor is available opacity: 0.5 } } } }; $.plot.plugins.push({ init: init, options: options, name: "meter", version: "1.0" }); })(jQuery);
使用的前置条件:需要引入flot的jquery组件,然后使用flot的API
给出一个简单的结果:
相关推荐
7. **社区活跃**:由于其开源性质,Flot有一个活跃的开发者社区,不断有新的插件和扩展被开发出来,如对触摸设备的支持、时间轴插件等,这些扩展极大地丰富了Flot的功能。 在使用Flot时,开发者通常会遵循以下步骤...
**jQuery绘图插件Flot详解** Flot是一款强大的基于JavaScript的绘图库,它完全依赖于jQuery,为Web开发者提供了在网页上绘制各种图表的能力。由Ole Laursen精心设计和开发,Flot以其易用性、灵活性和丰富的可视化...
总结来说,Flot是一个优秀的jQuery图表插件,它的易用性、强大的功能和丰富的图表类型使其成为开发者的首选之一。结合中文API文档,无论是新手还是经验丰富的开发者,都能够高效地利用Flot创建出美观且实用的数据...
Flot类库基于jQuery,支持绘制实时和可进行交互的图表
jQuery Flot是一个强大的JavaScript库,专门用于在网页上创建高质量的图表。它是基于jQuery构建的,因此能够充分利用jQuery的简洁API和广泛支持的优势。Flot图表插件以其灵活性、高效性和丰富的自定义选项而受到...
- **Flot**:作为jQuery的一个插件,Flot专门用于生成各种类型的图表,如折线图、柱状图、饼图等,支持时间序列数据和实时更新的数据流。 2. **特性** - **高效性能**:Flot利用HTML5的canvas元素进行绘图,提供...
在Web开发领域,数据可视化是不可或缺的一部分,而jQuery图表插件Flot则是JavaScript库中一个强大且灵活的工具,它为开发者提供了丰富的图表绘制功能。Flot以其出色的性能和易于使用的API,赢得了众多开发者的青睐。...
总结来说,jQuery的Flot是一个强大而灵活的绘图工具,它简化了Web应用程序中的图表制作,提供了丰富的交互功能和吸引人的外观。借助其对Ajax动态显示的支持,Flot能够帮助开发者创建出既实用又美观的数据展示界面,...
`jQuery Flot` 是一个基于 jQuery 的开源图表库,它允许开发者轻松地在网页上创建出各种复杂的图形,包括折线图、柱状图、饼图等。在本实例中,我们将关注如何使用 `jQuery Flot` 实现实时更新的折线图。实时更新的...
jQuery Flot 是一个用于在网页上绘制高质量图形的开源库,它基于 jQuery,因此易于集成到任何使用 jQuery 的项目中。这个库提供了丰富的选项和插件,可以创建出各种各样的图表,包括折线图、柱状图、饼图等。在本文...
jquery.flot.axislabels.js
总结,jQuery Flot是一个强大的JavaScript库,它简化了数据可视化的实现过程。通过理解和掌握Flot的基本概念、数据格式、配置选项、事件处理和插件,开发者可以轻松创建出美观且功能丰富的图表,以直观地展示和分析...
Flot是一个基于jQuery的图表库,特别适合那些需要在Web应用中嵌入图表的开发者。"flot-0.7.zip"包含了Flot的0.7版本。Flot的特点是其轻量级,它使用纯JavaScript进行绘图,依赖于HTML5的canvas元素,这使得它在现代...
Flot是一个强大的开源JavaScript库,专为jQuery设计,用于创建高质量、吸引人的数据可视化图表。它以其灵活性、易用性和性能而受到开发者们的广泛赞誉。Flot允许开发人员在网页上以动态、交互式的方式展示各种类型的...
浮点插件jQuery绘图库Flot的插件。系列注释使用此插件,您可以显示flot数据集中的特定点,而不是显示数据系列中的所有点。 要在绘图中显示点,必须包括seriesannotation.js文件,并且必须向每个数据集添加一个额外的...
jQuery Flot 是一个基于 JavaScript 的开源库,专门用于在 Web 页面上绘制高质量的统计图表。它充分利用了 jQuery 框架的易用性和灵活性,使得开发者无需深入学习复杂的图形库就能创建出丰富的交互式图表。Flot 的...
"jQuery饼状图效果"是一个关于利用JavaScript库jQuery实现饼状图展示的技术主题。饼状图是一种常用于显示整体与部分之间比例关系的图表,适用于展现各组成部分在整体中所占的比例。 jQuery是一个广泛使用的...
jquery.flot.time.js
Flot 是一个基于 jQuery 的开源图表插件,它提供了丰富的功能,用于在 Web 页面上创建交互式图表。这个库以其轻量级、灵活性和强大的性能而受到广泛的欢迎,尤其适合那些希望在网页上展示数据可视化结果的开发者。 ...