Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Details

Privacy

Go PRO Window blinds lowered to protect code. Code Editor with window blinds (raised) and a light blub turned on.

Keep it secret; keep it safe.

Private Pens are hidden everywhere on CodePen, except to you. You can still share them and other people can see them, they just can't find them through searching or browsing.

Upgrade to PRO

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

Template

Make Template?

Templates are Pens that can be used to start other Pens quickly from the create menu. The new Pen will copy all the code and settings from the template and make a new Pen (that is not a fork). You can view all of your templates, or learn more in the documentation.

Template URL

Any Pen can act as a template (even if you don't flip the toggle above) with a special URL you can use yourself or share with others. Here's this Pen's template URL:

Screenshot

Screenshots of Pens are shown in mobile browsers, RSS feeds, to users who chose images instead of iframes, and in social media sharing.

This Pen is using the default Screenshot, generated by CodePen. Upgrade to PRO to upload your own thumbnail that will be displayed on previews of this pen throughout the site and when sharing to social media.

Upgrade to PRO

HTML

              
                
    <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="../jquery.pista.js" type="text/javascript" charset="utf-8"></script>
    <link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" type="text/css" href="normalize.css">
    <link rel="stylesheet" type="text/css" href="style.css">

    <div class="content">
    <h1>Pista.js</h1>
    <p>Lightweight time chart library for jquery/zepto.js.<br/></p>
    <a target="_blank" href="https://github.com/urcoilbisurco/Pista.js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
    <!-- Place this tag where you want the button to render. -->
    <a class="github-button" href="https://github.com/urcoilbisurco/Pista.js" data-style="mega">Download on Github</a>
    
    
    <h3>Basic chart</h3>
    <div id="basic"></div>
    

    <h3>Multi lines chart</h3>
    <div id="multi"></div>    
    

    <h3>Curve lines chart</h3>
    <div id="curve"></div>
    
    

    <h3>Chart with goal</h3>
    <div id="goal"></div>
    
    

    <h3>Custom Y</h3>
    <div id="custom"></div>
    
    
    <h3>Colored Background</h3>
    <div id="fill"></div>
    
    
    
    <script>

    $(document).ready(function(){
      var data= [   { name:"first",
          data:[
              {value:12, date:"12/14/2014"},
              {value:32, date:"12/15/2014"},
              {value:56, date:"12/17/2014"},
              {value:45, date:"12/19/2014"}
            
            ]
          }
      ]
    
      // Basic
      options={
        height: 150,
        width: 600,
      }
      $("#basic").pista(data, options);
      
    
    data= [   { name:"first",
      data:[
          {value:12, date:"12/14/2014"},
          {value:32, date:"12/15/2014"},
          {value:56, date:"12/17/2014"},
          {value:45, date:"12/19/2014"}
        
        ]
      },
      { name:"second",
      data:[
          {value:13, date:"12/13/2014"},
          {value:30, date:"12/15/2014"},
          {value:26.6, date:"12/18/2014"},
          {value:33, date:"12/19/2014"}
        
        ]
      }
  ]
  // Multiple lines
  options={
    height: 150,
    width: 600,
  }
  $("#multi").pista(data, options);
      
      
      
      // Curve chart
      options={
        height: 150,
        width: 600,
        lines:{curve:true}
      }
      $("#curve").pista(data, options);
      
      // Goal chart
      options={
        height: 150,
        width: 600,
        goal: {show:true, value:23},
      }
      $("#goal").pista(data, options);
      
      
      // Goal chart
      options={
        height: 150,
        width: 600,
	      y:{margin:0.2, min:0, max:100}
      }
      $("#custom").pista(data, options);
      
      
      // Goal chart
      options={
        height: 150,
        width: 600,
        lines:{fill:true, fillOpacity:0.3}
      }
      $("#fill").pista(data, options);
      
    });
    </script>
    <!-- Place this tag right after the last button or just before your close body tag. -->
    <script async defer id="github-bjs" src="https://buttons.github.io/buttons.js"></script>

              
            
!

CSS

              
                /*! normalize.css v3.0.2 | MIT License | git.io/normalize */

/**
 * 1. Set default font family to sans-serif.
 * 2. Prevent iOS text size adjust after orientation change, without disabling
 *    user zoom.
 */

html {
  font-family: sans-serif; /* 1 */
  -ms-text-size-adjust: 100%; /* 2 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/**
 * Remove default margin.
 */

body {
  margin: 0;
}

/* HTML5 display definitions
   ========================================================================== */

/**
 * Correct `block` display not defined for any HTML5 element in IE 8/9.
 * Correct `block` display not defined for `details` or `summary` in IE 10/11
 * and Firefox.
 * Correct `block` display not defined for `main` in IE 11.
 */

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
  display: block;
}

/**
 * 1. Correct `inline-block` display not defined in IE 8/9.
 * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
 */

audio,
canvas,
progress,
video {
  display: inline-block; /* 1 */
  vertical-align: baseline; /* 2 */
}

/**
 * Prevent modern browsers from displaying `audio` without controls.
 * Remove excess height in iOS 5 devices.
 */

audio:not([controls]) {
  display: none;
  height: 0;
}

/**
 * Address `[hidden]` styling not present in IE 8/9/10.
 * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
 */

[hidden],
template {
  display: none;
}

/* Links
   ========================================================================== */

/**
 * Remove the gray background color from active links in IE 10.
 */

a {
  background-color: transparent;
}

/**
 * Improve readability when focused and also mouse hovered in all browsers.
 */

a:active,
a:hover {
  outline: 0;
}

/* Text-level semantics
   ========================================================================== */

/**
 * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
 */

abbr[title] {
  border-bottom: 1px dotted;
}

/**
 * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
 */

b,
strong {
  font-weight: bold;
}

/**
 * Address styling not present in Safari and Chrome.
 */

dfn {
  font-style: italic;
}

/**
 * Address variable `h1` font-size and margin within `section` and `article`
 * contexts in Firefox 4+, Safari, and Chrome.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/**
 * Address styling not present in IE 8/9.
 */

mark {
  background: #ff0;
  color: #000;
}

/**
 * Address inconsistent and variable font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` affecting `line-height` in all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sup {
  top: -0.5em;
}

sub {
  bottom: -0.25em;
}

/* Embedded content
   ========================================================================== */

/**
 * Remove border when inside `a` element in IE 8/9/10.
 */

img {
  border: 0;
}

/**
 * Correct overflow not hidden in IE 9/10/11.
 */

svg:not(:root) {
  overflow: hidden;
}

/* Grouping content
   ========================================================================== */

/**
 * Address margin not present in IE 8/9 and Safari.
 */

figure {
  margin: 1em 40px;
}

/**
 * Address differences between Firefox and other browsers.
 */

hr {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  height: 0;
}

/**
 * Contain overflow in all browsers.
 */

pre {
  overflow: auto;
}

/**
 * Address odd `em`-unit font size rendering in all browsers.
 */

code,
kbd,
pre,
samp {
  font-family: monospace, monospace;
  font-size: 1em;
}

/* Forms
   ========================================================================== */

/**
 * Known limitation: by default, Chrome and Safari on OS X allow very limited
 * styling of `select`, unless a `border` property is set.
 */

/**
 * 1. Correct color not being inherited.
 *    Known issue: affects color of disabled elements.
 * 2. Correct font properties not being inherited.
 * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
 */

button,
input,
optgroup,
select,
textarea {
  color: inherit; /* 1 */
  font: inherit; /* 2 */
  margin: 0; /* 3 */
}

/**
 * Address `overflow` set to `hidden` in IE 8/9/10/11.
 */

button {
  overflow: visible;
}

/**
 * Address inconsistent `text-transform` inheritance for `button` and `select`.
 * All other form control elements do not inherit `text-transform` values.
 * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
 * Correct `select` style inheritance in Firefox.
 */

button,
select {
  text-transform: none;
}

/**
 * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
 *    and `video` controls.
 * 2. Correct inability to style clickable `input` types in iOS.
 * 3. Improve usability and consistency of cursor style between image-type
 *    `input` and others.
 */

button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
  -webkit-appearance: button; /* 2 */
  cursor: pointer; /* 3 */
}

/**
 * Re-set default cursor for disabled elements.
 */

button[disabled],
html input[disabled] {
  cursor: default;
}

/**
 * Remove inner padding and border in Firefox 4+.
 */

button::-moz-focus-inner,
input::-moz-focus-inner {
  border: 0;
  padding: 0;
}

/**
 * Address Firefox 4+ setting `line-height` on `input` using `!important` in
 * the UA stylesheet.
 */

input {
  line-height: normal;
}

/**
 * It's recommended that you don't attempt to style these elements.
 * Firefox's implementation doesn't respect box-sizing, padding, or width.
 *
 * 1. Address box sizing set to `content-box` in IE 8/9/10.
 * 2. Remove excess padding in IE 8/9/10.
 */

input[type="checkbox"],
input[type="radio"] {
  box-sizing: border-box; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Fix the cursor style for Chrome's increment/decrement buttons. For certain
 * `font-size` values of the `input`, it causes the cursor style of the
 * decrement button to change from `default` to `text`.
 */

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
 * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
 *    (include `-moz` to future-proof).
 */

input[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box; /* 2 */
  box-sizing: content-box;
}

/**
 * Remove inner padding and search cancel button in Safari and Chrome on OS X.
 * Safari (but not Chrome) clips the cancel button when the search input has
 * padding (and `textfield` appearance).
 */

input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * Define consistent border, margin, and padding.
 */

fieldset {
  border: 1px solid #c0c0c0;
  margin: 0 2px;
  padding: 0.35em 0.625em 0.75em;
}

/**
 * 1. Correct `color` not being inherited in IE 8/9/10/11.
 * 2. Remove padding so people aren't caught out if they zero out fieldsets.
 */

legend {
  border: 0; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Remove default vertical scrollbar in IE 8/9/10/11.
 */

textarea {
  overflow: auto;
}

/**
 * Don't inherit the `font-weight` (applied by a rule above).
 * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
 */

optgroup {
  font-weight: bold;
}

/* Tables
   ========================================================================== */

/**
 * Remove most spacing between table cells.
 */

table {
  border-collapse: collapse;
  border-spacing: 0;
}

td,
th {
  padding: 0;
}
body{
  font-family: 'Lato', sans-serif;
  color:#666;
  background:#f4f4f4;
}

h1{
  margin:0;
  margin-bottom:30px;
}
p{
  margin-bottom:20px;
}
.content{
  min-height:1000px;
  padding-top:40px;
  background:white;
  border-left:1px solid #f9f9f9;
  border-right:1px solid #f9f9f9;
  width:100%;
  max-width:700px;
  margin:0 auto;
  text-align:center;
  padding-bottom:100px;
}
              
            
!

JS

              
                // Pista jQuery/zepto plugin version 0.1
// (c) 2012-2014 Francesco Marassi
// This work is licensed under the MIT License.


(function($, document) {
  var pista = $.fn.pista = function(data, options, hoverCb) {
    if (document.createElement("canvas").getContext) {
      this.each(function() {
          opts=$.extend(true, {}, pista.defaults, options)
          pista.graphers.call(this, data, opts, hoverCb)
      });
    }

    return this;
  };
  
  var u={
	  getTime:function(string_date){
		return new Date(string_date).getTime();
	  },
	  tooltipEvent:function(){
		  //TODO: check if the client is touch, then return 'touchend'
		  return 'mousemove';
	  },
	  createCanvas:function(width,height){
	    var canvas = document.createElement("canvas");
	  	canvas.setAttribute("width", width * devicePixelRatio)
	  	canvas.setAttribute("height", height * devicePixelRatio)
	  	if (devicePixelRatio != 1) {
	  		var style = "width:" + width + "px;height:" + height + "px"
	  		canvas.setAttribute("style", style)
	  	}
	  	return canvas
	  },
	  getYValues:function(elements, _y, goal){
		var y={}
		for(var i=0;i<elements.length;i++){
			
			var data=elements[i].data;
			
			for(var j=0;j<data.length;j++){
	  		  e=data[j].value;
	  		  if(i==0 & j==0){
	  			  y.min=y.max=e
	  		  }else{
	  			  y.min=Math.min(y.min, e)
	  			  y.max=Math.max(y.max, e)
	  		  }
			}
		}
		  
		if(_y.max){y.max= _y.max;}
		if(_y.min){y.min= _y.min;}
		
		if(goal.show){
		  	y.max=Math.max(y.max, goal.value);
			y.min=Math.min(y.min, goal.value);
		}
		  
		y.marginMin=y.min-y.min*_y.margin;
		y.marginMax=y.max+y.max*_y.margin;
		y.margin= (y.marginMax-y.marginMin)*_y.margin
		return y;
		},
		
	  getXValues:function(elements, _x){
		  var x={}
  		  for(var i=0;i<elements.length;i++){
			  var data=elements[i].data
			  if(i==0){
	 			 x.max=u.getTime(data[data.length-1].date);
	 			 x.min=u.getTime(data[0].date);
			  }else{
			 	 x.max=Math.max(x.max, u.getTime(data[data.length-1].date));
			 	x.min=Math.min(x.min, u.getTime(data[0].date));
		 	  }
  		  }
		  if(_x.max){x.max=u.getTime(_x.max)}
		  if(_x.min){x.min=u.getTime(_x.min)}
		  x.margin= _x.margin;
		  return x;
	  },
	  line:function(context, start,end, curve){
		if(curve){
			var mid={
				x: (start.x+end.x)/2, 
				y: (start.y+end.y)/2
			};
			// Draw line connecting the two points:
			context.quadraticCurveTo((start.x + mid.x) / 2, start.y, mid.x, mid.y);
			context.quadraticCurveTo((mid.x + end.x) / 2, end.y, end.x, end.y);
		}else{
			context.lineTo(end.x,end.y);
		}
	  },
	  fDate:function(d){
  		return d.getMonth()+1 + "/"+d.getDate();
	  },
	  deltaDays: function(min, max){
		  var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
		  return Math.round(Math.abs((min - max)/(oneDay)));
	  }
  }
  
  mainColor="#3BAFD7";
  secondaryColor="#E1523D"
  pista.defaults = {
      height: 100,
      width: 100,
	  x:{margin:15, min: null, max:null},
	  y:{margin:0.2, min:null, max:null},
	  goal: {show:false, value:23, color: mainColor},
	  tooltip: {show:true, maxRadius: 3},
	  lines: {show: true, fill: false, curve:false, strokeColor: [mainColor, secondaryColor], strokeWidth: 4, fillOpacity: 0.4, fillColor:[mainColor, secondaryColor]},
	  points:{show: true, strokeWidth:3.5, strokeColor:[mainColor, secondaryColor]},
	  labels:{
		  lineWidth: 0.3,
		  fontSize: 11,
		  x:{number: 7, show:true, color:"#858585", grid:false },
		  y:{number:4, show:true, color:"#858585", grid:true}}
    };

  var devicePixelRatio = window.devicePixelRatio || 1

  function log(tag, what){
	  console.log(tag+":");
	  console.log(what);
	  console.log("---");
  }
  
 
  pista.graphers=
    function(elements, opts, cb) {
		//the data will be in the format
		// [
		// 	{value:0, date: MM/dd/yyyy}, 
		// 	{value:0, date: 12/07/2012}, 
		// 	{value:0, date: 12/07/2012},
		// ]
		
		///////////////////////// GENERATE LABELS ////////////////////////////////////////////
		
		var canvas = u.createCanvas(opts.width, opts.height)
    	var context = canvas.getContext("2d");
    	var width = canvas.width;
    	var height = canvas.height;
		var marginBottom=20;
		if(opts.labels.x.show){
			
		}
		var y=u.getYValues(elements, opts.y, opts.goal);
		var x=u.getXValues(elements, opts.x);
		
		x.marginLeft=0;
		var canvasHeight=height-marginBottom;
		if(opts.labels.y.show){
			number=opts.labels.y.number;
			var labelHeight=canvasHeight/number;
			range=y.marginMax-y.marginMin;
			add=range/number;
			y.labels=[]
			context.fillStyle=opts.labels.y.color;
			context.lineStyle=opts.labels.y.color;
			context.strokeStyle="#D2D2D2";
			context.font=opts.labels.fontSize+"px" + $(this).css("font-family");
			
			var yMaxLength=0;
			for(var i=0; i<number; i++){
				v={y: canvasHeight-labelHeight*i, value: (y.marginMin+(add*i)).toFixed(2)}
				y.labels.push(v)
				context.fillText(v.value,1,v.y+3);
				//get the most long length to calculate the x.marginLeft
				if(i==0){yMaxLength=v.value.length}else{yMaxLength=Math.max(v.value.length, yMaxLength)}
			}
			
			x.marginLeft=x.margin + yMaxLength*(opts.labels.fontSize/2);
			if(opts.labels.y.grid){
				for(var i=0; i<y.labels.length;i++){
					v=y.labels[i].y;
					context.beginPath();
					context.lineWidth=opts.labels.lineWidth;
					context.moveTo(x.marginLeft, v);
					context.lineTo(width, v);
					context.closePath();
					context.stroke();
				}
			}	
		}
		if(opts.labels.x.show){
			number=elements.length;
			e=opts.labels.x.number;
			days=u.deltaDays(x.min, x.max)
			if(days<=e){
				skip=1;
			}else{
				skip=((days/e)).toFixed();
			}
			var labelWidth=(width-x.marginLeft-x.margin)/days;
			range=x.max-x.min;
			add=range/days;
			x.labels=[]
			context.fillStyle=opts.labels.y.color;
			context.lineStyle=opts.labels.y.color;
			context.strokeStyle="#D2D2D2";
			context.font=opts.labels.fontSize+"px" + $(this).css("font-family");
			
			for(var i=0;i<days;i++){
				if(i%skip==0){
					v={x:labelWidth*i, value: parseInt((x.min + (add*i)))}
					x.labels.push(v)
					context.textAlign='center';
					//log("date "+i, v.value);
					context.fillText(u.fDate(new Date(v.value)),x.marginLeft+v.x,height-4);
				
					if(opts.labels.x.grid){
						context.beginPath();
						context.lineWidth=opts.labels.lineWidth;
						context.moveTo(x.marginLeft+v.x, canvasHeight+5);
						context.lineTo(x.marginLeft+v.x, marginBottom);
						context.closePath();
						context.stroke();
					}	
				}
			}
			
		}
		
    	x.quotient = (width-(x.margin+ x.marginLeft)) / (x.max- x.min);
    	y.quotient = (canvasHeight) / (y.marginMax - y.marginMin);
    	var g_coords = [];
    	var i;
		
		///////////////////////// CREATE THE COORDS OBJECTS ////////////////////////////////////////////

		for (i = 0; i < elements.length; i++) {
			var data=elements[i].data;
			g_coords[i]=[]
			for(j=0;j<data.length;j++){
				var e=data[j]
				var time=u.getTime(e.date);
				var cx = ((time-x.min) * x.quotient)+x.marginLeft;
				var cy =canvasHeight - (y.quotient * (e.value - y.marginMin));
				g_coords[i].push({ x: cx, y: cy, date: time, value: e.value });
				
			}
		}
		
		
		///////////////////////// BEGIN DRAWING THE BACKGROUND ////////////////////////////////////////////
    	
		for(c=g_coords.length-1;c>=0;c--){
			coords=g_coords[c];
			if(coords.length>0){
				if(opts.lines.fill){
					context.beginPath();
					context.moveTo(coords[0].x, canvasHeight)
					context.lineTo(coords[0].x, coords[0].y)
					context.globalAlpha = opts.lines.fillOpacity;
					for (i = 0; i < coords.length - 1; i ++){
						
						u.line(context,coords[i], coords[i+1], opts.lines.curve)
					}
			
					context.fillStyle = opts.lines.fillColor[c];
					context.lineTo(coords[coords.length-1].x, canvasHeight);
					context.closePath();
					context.fill();
				}
				context.globalAlpha=1;
				
		
				///////////////////////// DRAW LINES ////////////////////////////////////////////
			
			
				if(opts.lines.show){
					context.beginPath();
					context.moveTo(coords[0].x, coords[0].y);
					for (i = 0; i < coords.length-1; i++) {
						u.line(context, coords[i], coords[i+1], opts.lines.curve)
					}
					context.lineWidth = opts.lines.strokeWidth * devicePixelRatio;
					context.strokeStyle = opts.lines.strokeColor[c];
					context.stroke();
				}
			
				///////////////////////// DRAW CIRCLES ////////////////////////////////////////////
				if(opts.points.show){
				
					for (i = 0; i < coords.length; i++) {
						var start=coords[i];
						// Draw line connecting the two points:
						context.beginPath();
						context.arc(start.x, start.y, opts.points.strokeWidth, 0, 2 * Math.PI);
						context.fillStyle=opts.points.strokeColor[c] || opts.lines.strokeColor[c];
						context.fill();
						context.strokeStyle=opts.points.strokeColor[c] || opts.lines.strokeColor[c];
						context.stroke();
					}
				
				}
			}
		}
		
			
			///////////////////////// DRAW GOAL ////////////////////////////////////////////
			
			
			if(opts.goal.show){
				var cy =canvasHeight- (y.quotient * (opts.goal.value - y.marginMin));
				context.beginPath();
				context.moveTo(x.marginLeft, cy);
				context.lineTo(width, cy);
				context.fillStyle=opts.points.strokeColor || opts.lines.strokeColor;
				context.lineWidth=2;
				context.fill();
				context.strokeStyle=opts.goal.color || opts.lines.strokeColor[0];
				context.stroke();
			}
						
						
						
			///////////////////////// EVENT FOR TOOLTIP ////////////////////////////////////////////
			
			
			if(opts.tooltip.show){
				canvas.addEventListener(u.tooltipEvent(), function(e) {
					var mouse={};
					
					if (e.pageX || e.pageY) { 
					  mouse.x = e.pageX;mouse.y = e.pageY;
					}
					else { 
					  mouse.x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 
					  mouse.y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 
					} 
					mouse.x -= canvas.offsetLeft;
					mouse.y -= canvas.offsetTop;
					var notFound=true;
					for(c=0;c<g_coords.length;c++){
						for (i = 0; i < g_coords[c].length; i++) {
							point=g_coords[c][i];
							if((Math.abs(point.x-mouse.x)<opts.points.strokeWidth*opts.tooltip.maxRadius) & (Math.abs(point.y-mouse.y)<opts.points.strokeWidth*opts.tooltip.maxRadius)){
								notFound=false;
								if(cb){cb({found:true, point: point, mouse: e})};
							}
						}
					}
					
					if(notFound && cb){cb({found:false})}
					
				}, false);
			}
		
		$(this).append(canvas);	
    }
	
})($, document);

              
            
!
999px
What did the colon say to the semicolon? Stop winking at me.

Console