(function(root,factory){if(typeof define==='function'&&define.amd){define(factory);}else if(typeof exports==='object'){module.exports=factory();}else{root.Sparkline=factory();}}(window,function(){function extend(specific,general){var obj={};for(var key in general){obj[key]=key in specific?specific[key]:general[key];}
return obj;}
function Sparkline(element,options){this.element=element;this.options=extend(options||{},Sparkline.options);init:{this.element.innerHTML="<canvas></canvas>";this.canvas=this.element.firstChild;this.context=this.canvas.getContext("2d");this.ratio=window.devicePixelRatio||1;if(this.options.tooltip){this.canvas.style.position="relative";this.canvas.onmousemove=showTooltip.bind(this);}}}
Sparkline.options={width:100,height:null,lineColor:"black",lineWidth:1.5,startColor:"transparent",endColor:"black",maxColor:"transparent",minColor:"transparent",minValue:null,maxValue:null,minMaxValue:null,maxMinValue:null,dotRadius:2.5,tooltip:null,fillBelow:true,fillLighten:0.5,startLine:false,endLine:false,minLine:false,maxLine:false,bottomLine:false,topLine:false,averageLine:false};Sparkline.init=function(element,options){return new Sparkline(element,options);};Sparkline.draw=function(element,points,options){var sparkline=new Sparkline(element,options);sparkline.draw(points);return sparkline;}
function getY(minValue,maxValue,offsetY,height,index){var range=maxValue-minValue;if(range==0){return offsetY+height/2;}else{return(offsetY+height)-((this[index]-minValue)/range)*height;}}
function drawDot(radius,x1,x2,color,line,x,y){this.context.beginPath();this.context.fillStyle=color;this.context.arc(x,y,radius,0,Math.PI*2,false);this.context.fill();drawLine.call(this,x1,x2,line,x,y);}
function drawLine(x1,x2,style,x,y){if(!style)return;this.context.save();this.context.strokeStyle=style.color||'black';this.context.lineWidth=(style.width||1)*this.ratio;this.context.globalAlpha=style.alpha||1;this.context.beginPath();this.context.moveTo(style.direction!='right'?x1:x,y);this.context.lineTo(style.direction!='left'?x2:x,y);this.context.stroke();this.context.restore();}
function showTooltip(e){var x=e.offsetX||e.layerX||0;var delta=((this.options.width-this.options.dotRadius*2)/(this.points.length-1));var index=minmax(0,Math.round((x-this.options.dotRadius)/delta),this.points.length-1);this.canvas.title=this.options.tooltip(this.points[index],index,this.points);}
Sparkline.prototype.draw=function(points){points=points||[];this.points=points;this.canvas.width=this.options.width*this.ratio;this.canvas.style.width=this.options.width+'px';var pxHeight=this.options.height||this.element.offsetHeight;this.canvas.height=pxHeight*this.ratio;this.canvas.style.height=pxHeight+'px';var lineWidth=this.options.lineWidth*this.ratio;var offsetX=Math.max(this.options.dotRadius*this.ratio,lineWidth/2);var offsetY=Math.max(this.options.dotRadius*this.ratio,lineWidth/2);var width=this.canvas.width-offsetX*2;var height=this.canvas.height-offsetY*2;var minValue=Math.min.apply(Math,points);var maxValue=Math.max.apply(Math,points);var bottomValue=this.options.minValue!=undefined?this.options.minValue:Math.min(minValue,this.options.maxMinValue!=undefined?this.options.maxMinValue:minValue);var topValue=this.options.maxValue!=undefined?this.options.maxValue:Math.max(maxValue,this.options.minMaxValue!=undefined?this.options.minMaxValue:maxValue);var minX=offsetX;var maxX=offsetX;var x=offsetX;var y=getY.bind(points,bottomValue,topValue,offsetY,height);var delta=width/(points.length-1);var dot=drawDot.bind(this,this.options.dotRadius*this.ratio,offsetX,width+offsetX);var line=drawLine.bind(this,offsetX,width+offsetX);this.context.save();this.context.strokeStyle=this.options.lineColor;this.context.fillStyle=this.options.lineColor;this.context.lineWidth=lineWidth;this.context.lineCap='round';this.context.lineJoin='round';if(this.options.fillBelow&&points.length>1){this.context.save();this.context.beginPath();this.context.moveTo(x,y(0));for(var i=1;i<points.length;i++){x+=delta;minX=points[i]==minValue?x:minX;maxX=points[i]==maxValue?x:maxX;this.context.lineTo(x,y(i));}
this.context.lineTo(width+offsetX,height+offsetY+lineWidth/2);this.context.lineTo(offsetX,height+offsetY+lineWidth/2);this.context.fill();if(this.options.fillLighten>0){this.context.fillStyle='white';this.context.globalAlpha=this.options.fillLighten;this.context.fill();this.context.globalAlpha=1;}else if(this.options.fillLighten<0){this.context.fillStyle='black';this.context.globalAlpha=-this.options.fillLighten;this.context.fill();}
this.context.restore();}
x=offsetX;this.context.beginPath();this.context.moveTo(x,y(0));for(var i=1;i<points.length;i++){x+=delta;this.context.lineTo(x,y(i));}
this.context.stroke();this.context.restore();line(this.options.bottomLine,0,offsetY);line(this.options.topLine,0,height+offsetY+lineWidth/2);dot(this.options.startColor,this.options.startLine,offsetX+(points.length==1?width/2:0),y(0));dot(this.options.endColor,this.options.endLine,offsetX+(points.length==1?width/2:width),y(points.length-1));dot(this.options.minColor,this.options.minLine,minX+(points.length==1?width/2:0),y(points.indexOf(minValue)));dot(this.options.maxColor,this.options.maxLine,maxX+(points.length==1?width/2:0),y(points.indexOf(maxValue)));}
function minmax(a,b,c){return Math.max(a,Math.min(b,c));}
return Sparkline;}));