gl-vis/regl-scatter2d · index.js
javascript logo
function (regl, options) {
	var scatter = new Scatter(regl, options)

	var render = scatter.render.bind(scatter)

	// expose API
	extend(render, {
		render: render,
		update: scatter.update.bind(scatter),
		draw: scatter.draw.bind(scatter),
		destroy: scatter.destroy.bind(scatter),
		regl: scatter.regl,
		gl: scatter.gl,
		canvas: scatter.gl.canvas,
		groups: scatter.groups,
		markers: scatter.markerCache,
		palette: scatter.palette
	})

	return render
}
Similar code snippets
1.
gl-vis/regl-scatter2d · bundle.js
Match rating: 76.78% · See similar code snippets
javascript logo
function reglScatter2d(regl, options) {
  var scatter$$1 = new scatter(regl, options);
  var render = scatter$$1.render.bind(scatter$$1); // expose API

  extend$1(render, {
    render: render,
    update: scatter$$1.update.bind(scatter$$1),
    draw: scatter$$1.draw.bind(scatter$$1),
    destroy: scatter$$1.destroy.bind(scatter$$1),
    regl: scatter$$1.regl,
    gl: scatter$$1.gl,
    canvas: scatter$$1.gl.canvas,
    groups: scatter$$1.groups,
    markers: scatter$$1.markerCache,
    palette: scatter$$1.palette
  });
  return render;
}
2.
maartenbreddels/ipyvolume · figure.js
Match rating: 73.53% · See similar code snippets
javascript logo
function() {
        var scatters = this.model.get('scatters'); // This is always a list?
        if (scatters.length != 0) { // So now check if list has length 0
            var current_sct_cids = []
            // Add new scatter if not already as scatter view in figure
            _.each(scatters, scatter_model => {
                current_sct_cids.push(scatter_model.cid);
                if (!(scatter_model.cid in this.scatter_views)) {
                    var options = {
                        parent: this
                    }
                    var scatter_view = new scatter.ScatterView({
                        options: options,
                        model: scatter_model
                    })
                    scatter_view.render()
                    this.scatter_views[scatter_model.cid] = scatter_view
                }
            }, this)

            // Remove old scatters not contained in scatters
            _.each(this.scatter_views, (sct, cid) => {
                if (current_sct_cids.indexOf(cid) == -1) {
                    sct.remove_from_scene();
                    delete this.scatter_views[cid];
                }
            }, this)
        } else {
            this.scatter_views = {}
        }
    }
3.
gl-vis/regl-scatter2d · scatter.js
Match rating: 52.76% · See similar code snippets
javascript logo
function Scatter (regl, options) {
	if (!(this instanceof Scatter)) return new Scatter(regl, options)

	if (typeof regl === 'function') {
		if (!options) options = {}
		options.regl = regl
	}
	else {
		options = regl
		regl = null
	}

	if (options && options.length) options.positions = options

	regl = options.regl

	// persistent variables
	let gl = regl._gl, paletteTexture, palette = [], paletteIds = {},

		// state
		groups = [],

		// textures for marker keys
		markerTextures = [null],
		markerCache = [null]

	const maxColors = 255, maxSize = 100

	// direct color buffer mode
	// IE does not support palette anyways
	this.tooManyColors = ie

	// texture with color palette
	paletteTexture = regl.texture({
		data: new Uint8Array(maxColors * 4),
		width: maxColors,
		height: 1,
		type: 'uint8',
		format: 'rgba',
		wrapS: 'clamp',
		wrapT: 'clamp',
		mag: 'nearest',
		min: 'nearest'
	})

	extend(this, {
		regl,
		gl,
		groups,
		markerCache,
		markerTextures,
		palette,
		paletteIds,
		paletteTexture,
		maxColors,
		maxSize,
		canvas: gl.canvas
	})

	this.update(options)

	// common shader options
	let shaderOptions = {
		uniforms: {
			pixelRatio: regl.context('pixelRatio'),
			palette: paletteTexture,
			paletteSize: (ctx, prop) => [this.tooManyColors ? 0 : maxColors, paletteTexture.height],
			scale: regl.prop('scale'),
			scaleFract: regl.prop('scaleFract'),
			translate: regl.prop('translate'),
			translateFract: regl.prop('translateFract'),
			opacity: regl.prop('opacity'),
			marker: regl.prop('markerTexture'),
		},

		attributes: {
			// FIXME: optimize these parts
			x: (ctx, prop) => prop.xAttr || {
				buffer: prop.positionBuffer,
				stride: 8,
				offset: 0
			},
			y: (ctx, prop) => prop.yAttr || {
				buffer: prop.positionBuffer,
				stride: 8,
				offset: 4
			},
			xFract: (ctx, prop) => prop.xAttr ? { constant: [0, 0] } : {
				buffer: prop.positionFractBuffer,
				stride: 8,
				offset: 0
			},
			yFract: (ctx, prop) => prop.yAttr ? { constant: [0, 0] } : {
				buffer: prop.positionFractBuffer,
				stride: 8,
				offset: 4
			},
			size: (ctx, prop) => prop.size.length ? {
				buffer: prop.sizeBuffer,
				stride: 2,
				offset: 0
			} : {
				constant: [ Math.round(prop.size * 255 / this.maxSize) ]
			},
			borderSize: (ctx, prop) => prop.borderSize.length ? {
				buffer: prop.sizeBuffer,
				stride: 2,
				offset: 1
			} : {
				constant: [ Math.round(prop.borderSize * 255 / this.maxSize) ]
			},
			colorId: (ctx, prop) => prop.color.length ? {
				buffer: prop.colorBuffer,
				stride: this.tooManyColors ? 8 : 4,
				offset: 0
			} : {
				constant: this.tooManyColors ? palette.slice(prop.color * 4, prop.color * 4 + 4) : [ prop.color ]
			},
			borderColorId: (ctx, prop) => prop.borderColor.length ? {
				buffer: prop.colorBuffer,
				stride: this.tooManyColors ? 8 : 4,
				offset: this.tooManyColors ? 4 : 2
			} : {
				constant: this.tooManyColors ? palette.slice(prop.borderColor * 4, prop.borderColor * 4 + 4) : [ prop.borderColor ]
			},
			isActive: (ctx, prop) => prop.activation === true ? { constant: [1] } : prop.activation ? prop.activation : { constant: [0] }
		},

		blend: {
			enable: true,
			color: [0,0,0,1],

			// photoshop blending
			func: {
				srcRGB: 'src alpha',
				dstRGB: 'one minus src alpha',
				srcAlpha: 'one minus dst alpha',
				dstAlpha: 'one'
			}
		},

		scissor: {
			enable: true,
			box: regl.prop('viewport')
		},
		viewport: regl.prop('viewport'),

		stencil: {enable: false},
		depth: {enable: false},

		elements: regl.prop('elements'),
		count: regl.prop('count'),
		offset: regl.prop('offset'),

		primitive: 'points'
	}

	// draw sdf-marker
	let markerOptions = extend({}, shaderOptions)
	markerOptions.frag = glslify('./marker-frag.glsl')
	markerOptions.vert = glslify('./marker-vert.glsl')

	this.drawMarker = regl(markerOptions)

	// draw circle
	let circleOptions = extend({}, shaderOptions)
	circleOptions.frag = glslify('./circle-frag.glsl')
	circleOptions.vert = glslify('./circle-vert.glsl')

	// polyfill IE
	if (ie) {
		circleOptions.frag = circleOptions.frag.replace('smoothstep', 'smoothStep')
		markerOptions.frag = markerOptions.frag.replace('smoothstep', 'smoothStep')
	}

	this.drawCircle = regl(circleOptions)
}
4.
MakerCollider/node-red-contrib-smartnode-hook · RGraph.common.core.js
Match rating: 51.53% · See similar code snippets
javascript logo
function (obj)
    {
        var prop = obj.properties;
        var co   = obj.context;
        var ca   = obj.canvas;

        var gutterLeft    = prop['chart.gutter.left'];
        var gutterRight   = prop['chart.gutter.right'];
        var gutterTop     = prop['chart.gutter.top'];
        var gutterBottom  = prop['chart.gutter.bottom'];


        co.strokeStyle = '#aaa';
        co.fillStyle = '#ddd';

        // Draw the vertical left side
        co.beginPath();
            co.moveTo(gutterLeft, gutterTop);
            co.lineTo(gutterLeft + 10, gutterTop - 5);
            co.lineTo(gutterLeft + 10, ca.height - gutterBottom - 5);
            co.lineTo(gutterLeft, ca.height - gutterBottom);

            // Draw the bottom floor
            co.moveTo(gutterLeft, ca.height - gutterBottom);
            co.lineTo(gutterLeft + 10, ca.height - gutterBottom - 5);
            co.lineTo(ca.width - gutterRight + 10,  ca.height - gutterBottom - 5);
            co.lineTo(ca.width - gutterRight, ca.height - gutterBottom);
        co.closePath();
        
        co.stroke();
        co.fill();
    }
5.
MakerCollider/node-red-contrib-smartnode-hook · RGraph.rose.js
Match rating: 51.12% · See similar code snippets
javascript logo
function ()
        {
            /**
            * Fire the onbeforedraw event
            */
            RG.FireCustomEvent(this, 'onbeforedraw');
    
    
    
            /**
            * This doesn't affect the chart, but is used for compatibility
            */
            this.gutterLeft   = prop['chart.gutter.left'];
            this.gutterRight  = prop['chart.gutter.right'];
            this.gutterTop    = prop['chart.gutter.top'];
            this.gutterBottom = prop['chart.gutter.bottom'];
    
            // Calculate the radius
            this.radius       = (Math.min(ca.width - this.gutterLeft - this.gutterRight, ca.height - this.gutterTop - this.gutterBottom) / 2);
            this.centerx      = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
            this.centery      = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
            this.angles       = [];
            this.angles2      = [];
            this.total        = 0;
            this.startRadians = prop['chart.angles.start'];
            this.coordsText   = [];
            
            /**
            * Change the centerx marginally if the key is defined
            */
            if (prop['chart.key'] && prop['chart.key'].length > 0 && prop['chart.key'].length >= 3) {
                this.centerx = this.centerx - this.gutterRight + 5;
            }
    
    
    
            // User specified radius, centerx and centery
            if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
            if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
            if (typeof(prop['chart.radius']) == 'number')  this.radius  = prop['chart.radius'];
    
            /**
            * Parse the colors for gradients. Its down here so that the center X/Y can be used
            */
            if (!this.colorsParsed) {
    
                this.parseColors();
    
                // Don't want to do this again
                this.colorsParsed = true;
            }
    
            this.drawBackground();


            this.DrawRose();
            this.DrawLabels();

            /**
            * Set the strokestyle to transparent because of a strange double stroke bug
            * 
            * DO NOT REMOVE
            */
            co.strokeStyle = 'rgba(0,0,0,0)'


            /**
            * Setup the context menu if required
            */
            if (prop['chart.contextmenu']) {
                RG.ShowContext(this);
            }
    
            
            /**
            * This function enables resizing
            */
            if (prop['chart.resizable']) {
                RG.AllowResizing(this);
            }
    
            
            /**
            * This function enables adjusting
            */
            if (prop['chart.adjustable']) {
                RG.AllowAdjusting(this);
            }
    
    
            /**
            * This installs the event listeners
            */
            RG.InstallEventListeners(this);



            /**
            * Fire the onfirstdraw event
            */
            if (this.firstDraw) {
                RG.fireCustomEvent(this, 'onfirstdraw');
                this.firstDraw = false;
                this.firstDrawFunc();
            }



            /**
            * Fire the RGraph ondraw event
            */
            RG.FireCustomEvent(this, 'ondraw');
            
            return this;
        }
6.
MakerCollider/node-red-contrib-smartnode-hook · RGraph.rscatter.js
Match rating: 50.95% · See similar code snippets
javascript logo
function ()
        {
            /**
            * Fire the onbeforedraw event
            */
            RG.FireCustomEvent(this, 'onbeforedraw');
    
    
            /**
            * This doesn't affect the chart, but is used for compatibility
            */
            this.gutterLeft   = prop['chart.gutter.left'];
            this.gutterRight  = prop['chart.gutter.right'];
            this.gutterTop    = prop['chart.gutter.top'];
            this.gutterBottom = prop['chart.gutter.bottom'];
    
            // Calculate the radius
            this.radius  = (Math.min(ca.width - this.gutterLeft - this.gutterRight, ca.height - this.gutterTop - this.gutterBottom) / 2);
            this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
            this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
            this.coords  = [];
            this.coords2 = [];



            /**
            * Stop this growing uncontrollably
            */
            this.coordsText = [];




            /**
            * If there's a user specified radius/centerx/centery, use them
            */
            if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
            if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
            if (typeof(prop['chart.radius'])  == 'number') this.radius  = prop['chart.radius'];
    
    
    
            /**
            * Parse the colors for gradients. Its down here so that the center X/Y can be used
            */
            if (!this.colorsParsed) {
    
                this.parseColors();
    
                // Don't want to do this again
                this.colorsParsed = true;
            }
    
    
            /**
            * Work out the scale
            */
            var max = prop['chart.ymax'];
            var min = prop['chart.ymin'];
            
            if (typeof(max) == 'number') {
                this.max    = max;
                this.scale2 = RG.getScale2(this, {'max':max,
                                                  'min':min,
                                                  'strict':true,
                                                  'scale.decimals':Number(prop['chart.scale.decimals']),
                                                  'scale.point':prop['chart.scale.point'],
                                                  'scale.thousand':prop['chart.scale.thousand'],
                                                  'scale.round':prop['chart.scale.round'],
                                                  'units.pre':prop['chart.units.pre'],
                                                  'units.post':prop['chart.units.post'],
                                                  'ylabels.count':prop['chart.labels.count']
                                                 });
            } else {
    
                for (var i=0; i<this.data.length; i+=1) {
                    for (var j=0,len=this.data[i].length; j<len; j+=1) {
                        this.max = Math.max(this.max, this.data[i][j][1]);
                    }
                }

                this.min = prop['chart.ymin'];
    
                this.scale2 = RG.getScale2(this, {'max':this.max,
                                                  'min':min,
                                                  'scale.decimals':Number(prop['chart.scale.decimals']),
                                                  'scale.point':prop['chart.scale.point'],
                                                  'scale.thousand':prop['chart.scale.thousand'],
                                                  'scale.round':prop['chart.scale.round'],
                                                  'units.pre':prop['chart.units.pre'],
                                                  'units.post':prop['chart.units.post'],
                                                  'ylabels.count':prop['chart.labels.count']
                                                 });
                this.max = this.scale2.max;
            }
    
            /**
            * Change the centerx marginally if the key is defined
            */
            if (prop['chart.key'] && prop['chart.key'].length > 0 && prop['chart.key'].length >= 3) {
                this.centerx = this.centerx - prop['chart.gutter.right'] + 5;
            }
            
            /**
            * Populate the colors array for the purposes of generating the key
            */
            if (typeof(prop['chart.key']) == 'object' && RG.is_array(prop['chart.key']) && prop['chart.key'][0]) {

                // Reset the colors array
                prop['chart.colors'] = [];

                for (var i=0; i<this.data.length; i+=1) {
                    for (var j=0,len=this.data[i].length; j<len; j+=1) {
                        if (typeof this.data[i][j][2] == 'string') {
                            prop['chart.colors'].push(this.data[i][j][2]);
                        }
                    }
                }
            }

    
    
    
            /**
            * Populate the chart.tooltips array
            */
            this.Set('chart.tooltips', []);

            for (var i=0; i<this.data.length; i+=1) {
                for (var j=0,len=this.data[i].length; j<len; j+=1) {
                    if (typeof this.data[i][j][3] == 'string') {
                        prop['chart.tooltips'].push(this.data[i][j][3]);
                    }
                }
            }
    
    
    
            // This resets the chart drawing state
            co.beginPath();
    
            this.DrawBackground();
            this.DrawRscatter();
            this.DrawLabels();
    
            /**
            * Setup the context menu if required
            */
            if (prop['chart.contextmenu']) {
                RG.ShowContext(this);
            }
    
    
    
            // Draw the title if any has been set
            if (prop['chart.title']) {
                RG.DrawTitle(this,
                             prop['chart.title'],
                             this.centery - this.radius - 10,
                             this.centerx,
                             prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2);
            }
    
            
            /**
            * This function enables resizing
            */
            if (prop['chart.resizable']) {
                RG.AllowResizing(this);
            }
    
    
            /**
            * This installs the event listeners
            */
            RG.InstallEventListeners(this);




            /**
            * Fire the onfirstdraw event
            */
            if (this.firstDraw) {
                RG.fireCustomEvent(this, 'onfirstdraw');
                this.firstDraw = false;
                this.firstDrawFunc();
            }




            /**
            * Fire the RGraph ondraw event
            */
            RG.FireCustomEvent(this, 'ondraw');




            return this;
        }
7.
MakerCollider/node-red-contrib-smartnode-hook · RGraph.gauge.js
Match rating: 50.76% · See similar code snippets
javascript logo
function ()
        {
            /**
            * Fire the onbeforedraw event
            */
            RG.FireCustomEvent(this, 'onbeforedraw');
    
    
    
            /**
            * Store the value (for animation primarily
            */
            this.currentValue = this.value;
    
    
            /**
            * This is new in May 2011 and facilitates indiviual gutter settings,
            * eg chart.gutter.left
            */
            this.gutterLeft   = prop['chart.gutter.left'];
            this.gutterRight  = prop['chart.gutter.right'];
            this.gutterTop    = prop['chart.gutter.top'];
            this.gutterBottom = prop['chart.gutter.bottom'];
            
            this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
            this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
            this.radius  = Math.min(
                                    ((ca.width - this.gutterLeft - this.gutterRight) / 2),
                                    ((ca.height - this.gutterTop - this.gutterBottom) / 2)
                                   );
            this.startAngle = prop['chart.angles.start'] ? prop['chart.angles.start'] : (RG.HALFPI / 3) + RG.HALFPI;
            this.endAngle   = prop['chart.angles.end'] ? prop['chart.angles.end'] : RG.TWOPI + RG.HALFPI - (RG.HALFPI / 3);
            
            
            /**
            * Reset this so it doesn't keep growing
            */
            this.coordsText = [];
    
    
    
            /**
            * You can now override the positioning and radius if you so wish.
            */
            if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
            if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
            if (typeof(prop['chart.radius']) == 'number')  this.radius  = prop['chart.radius'];
    
            /**
            * Parse the colors. This allows for simple gradient syntax
            */
            if (!this.colorsParsed) {
                this.parseColors();
                
                // Don't want to do this again
                this.colorsParsed = true;
            }
    
    
            // This has to be in the constructor
            this.centerpinRadius = 0.16 * this.radius;
            
            if (typeof(prop['chart.centerpin.radius']) == 'number') {
                this.centerpinRadius = prop['chart.centerpin.radius'];
            }
    
    
    
            /**
            * Setup the context menu if required
            */
            if (prop['chart.contextmenu']) {
                RG.ShowContext(this);
            }
    
    
    
            // DRAW THE CHART HERE
            this.DrawBackGround();
            this.DrawGradient();
            this.DrawColorBands();
            this.DrawSmallTickmarks();
            this.DrawMediumTickmarks();
            this.DrawBigTickmarks();
            this.DrawLabels();
            this.DrawTopTitle();
            this.DrawBottomTitle();
    
            if (typeof(this.value) == 'object') {
                for (var i=0; i<this.value.length; ++i) {
                    this.DrawNeedle(this.value[i], prop['chart.needle.colors'][i], i);
                }
            } else {
                this.DrawNeedle(this.value, prop['chart.needle.colors'][0], 0);
            }
    
            this.DrawCenterpin();
            
            /**
            * This function enables resizing
            */
            if (prop['chart.resizable']) {
                RG.AllowResizing(this);
            }
    
    
            /**
            * This installs the event listeners
            */
            RG.InstallEventListeners(this);
    

            /**
            * Fire the onfirstdraw event
            */
            if (this.firstDraw) {
                RG.fireCustomEvent(this, 'onfirstdraw');
                this.firstDraw = false;
                this.firstDrawFunc();
            }




            /**
            * Fire the RGraph ondraw event
            */
            RG.FireCustomEvent(this, 'ondraw');
            
            return this;
        }
8.
gilbitron/Raneto · ghostdown.js
Match rating: 50.61% · See similar code snippets
javascript logo
function updateGutters(cm) {
    var gutters = cm.display.gutters, specs = cm.options.gutters;
    removeChildren(gutters);
    for (var i = 0; i < specs.length; ++i) {
      var gutterClass = specs[i];
      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
      if (gutterClass == "CodeMirror-linenumbers") {
        cm.display.lineGutter = gElt;
        gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
      }
    }
    gutters.style.display = i ? "" : "none";
  }
9.
eschnou/ardrone-webflight · battery.js
Match rating: 50.6% · See similar code snippets
javascript logo
function (window, $, undefined) {
    'use strict';

    var Battery;

    Battery = function Battery(cockpit) {
        console.log("Loading Battery indicator plugin.");

        // Instance variables
        this.cockpit = cockpit;
        this.level = 100;

        // Add required UI elements
        $(".header-container .wrapper").prepend('<div id="battery"><canvas class="gauge" width="50px;" height="25px;" /><span class="level">100%</span></div>');
        this.ctx = $('#battery .gauge').get(0).getContext('2d');
        
        // Bind to navdata events on websockets
        var self = this;
        this.cockpit.socket.on('navdata', function(data) {
            if (!jQuery.isEmptyObject(data)) {
                requestAnimationFrame(function() {
                    self.render(data);
                });
            }
        });

        // Initial draw
        this.draw();
    };

    Battery.prototype.render = function(data) {
        this.level = data.demo.batteryPercentage;
        $("#battery .level").text(this.level + '%');
        this.draw();
    }

    Battery.prototype.draw = function() {
        var cw = this.ctx.canvas.width;
        var ch = this.ctx.canvas.height;

        this.ctx.clearRect(0, 0, cw, ch);
        this.ctx.save();
        this.ctx.strokeStyle = 'grey';
        this.ctx.fillStyle = 'grey';
        this.ctx.lineWidth = 2;
        roundRect(this.ctx, 5, 1, 40, 20);
        this.ctx.fillRect(45, 5, 4, 12);
         
        var width = Math.floor(this.level / 100 * 35);
        this.ctx.fillStyle = this.getColor();
        roundRect(this.ctx, 8, 3, width, 15, 3, true, false);
          
        this.ctx.restore();
    }

    Battery.prototype.getColor = function() {
        if (this.level > 90) {
            return 'lightgreen';
        } else if (this.level > 80) {
            return 'green';
        } else if (this.level > 70) {
            return 'darkgreen';
        } else if (this.level > 60) {
            return 'lightyellow';
        } else if (this.level > 50) {
            return 'yellow';
        } else if (this.level > 40) {
            return 'darkyellow';
        } else if (this.level > 30) {
            return 'lightred';
        } else if (this.level > 20) {
            return 'red';
        } else {
            return 'darkred';
        }
    }

    window.Cockpit.plugins.push(Battery);

}
10.
MakerCollider/node-red-contrib-smartnode-hook · RGraph.waterfall.js
Match rating: 50.35% · See similar code snippets
javascript logo
function ()
        {
            /**
            * Fire the onbeforedraw event
            */
            RGraph.FireCustomEvent(this, 'onbeforedraw');
            
    
            /**
            * Parse the colors. This allows for simple gradient syntax
            */
            if (!this.colorsParsed) {
                this.parseColors();
                
                // Don't want to do this again
                this.colorsParsed = true;
            }
    
            
            /**
            * Draw the background image
            */
            RGraph.DrawBackgroundImage(this);
            
            /**
            * This is new in May 2011 and facilitates indiviual gutter settings,
            * eg chart.gutter.left
            */
            this.gutterLeft   = prop['chart.gutter.left'];
            this.gutterRight  = prop['chart.gutter.right'];
            this.gutterTop    = prop['chart.gutter.top'];
            this.gutterBottom = prop['chart.gutter.bottom'];

            /**
            * Stop the coords array from growing uncontrollably
            */
            this.coords = [];



            /**
            * Stop this growing uncontrollably
            */
            this.coordsText = [];




            /**
            * This gets used a lot
            */
            this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;

            /**
            * Work out a few things. They need to be here because they depend on things you can change after you instantiate the object
            */
            this.max            = 0;
            this.grapharea      = ca.height - this.gutterTop - this.gutterBottom;
            this.graphwidth     = ca.width - this.gutterLeft - this.gutterRight;
            this.halfTextHeight = prop['chart.text.size'] / 2;
    
    
            /**
            * Work out the maximum value
            */
            this.max     = this.getMax(this.data);
    
            var decimals = prop['chart.scale.decimals'];
            this.scale2 = RGraph.getScale2(this, {'max':typeof(prop['chart.ymax']) == 'number' ? prop['chart.ymax'] : this.max,
                                                  'min':prop['chart.xmin'],
                                                  'strict': typeof(prop['chart.ymax']) == 'number' ? true : false,
                                                  'scale.decimals':Number(decimals),
                                                  'scale.point':prop['chart.scale.point'],
                                                  'scale.thousand':prop['chart.scale.thousand'],
                                                  'scale.round':prop['chart.scale.round'],
                                                  'units.pre':prop['chart.units.pre'],
                                                  'units.post':prop['chart.units.post'],
                                                  'ylabels.count':prop['chart.labels.count']
                                                 });
    
            this.max     = this.scale2.max;
    
    
            // Draw the background hbars
            RGraph.DrawBars(this)

            // Progressively Draw the chart
            RG.background.Draw(this);
    
            this.DrawAxes();
            this.Drawbars();
            this.DrawLabels();
            
            /**
            * If the X axis is at the bottom - draw the it again so that it appears "on top" of the bars
            */
            if (prop['chart.xaxispos'] == 'bottom' && prop['chart.noaxes'] == false && prop['chart.noxaxis'] == false) {
                co.strokeStyle = prop['chart.axis.color'];
                co.strokeRect(prop['chart.gutter.left'], ca.height - prop['chart.gutter.bottom'], ca.width - this.gutterLeft - this.gutterRight, 0);
            }
    
            /**
            * Setup the context menu if required
            */
            if (prop['chart.contextmenu']) {
                RG.ShowContext(this);
            }
    
            
            /**
            * This function enables resizing
            */
            if (prop['chart.resizable']) {
                RG.AllowResizing(this);
            }
    
    
            /**
            * This installs the event listeners
            */
            RG.InstallEventListeners(this);



            /**
            * Fire the onfirstdraw event
            */
            if (this.firstDraw) {
                RG.fireCustomEvent(this, 'onfirstdraw');
                this.firstDraw = false;
                this.firstDrawFunc();
            }




            /**
            * Fire the RGraph ondraw event
            */
            RG.FireCustomEvent(this, 'ondraw');
            
            return this;
        }