MISCELLANEOUS TECHNICAL ARTICLES BY Dr A R COLLINS

Cango Axes User Guide

Cango axes drawing extension

The Cango Axes extension module provides additional methods to the Cango library to simplify generating graph axes when plotting data with Cango. Also included in the module are additional Cango methods for drawing arrows. Earlier versions of CangoAxes had methods for drawing vector text and text HTML text. These have been split off to the CangoTextUtils module.

The extension requires the Cango canvas graphics library Version 16 or later. Download the source code from CangoAxes-8v00.js and the minified version at CangoAxes-8v00-min.js

These additional Cango methods added by loading the CangoAxes-8v00.js file are:

drawAxes
drawBoxAxes
drawArrow
drawArrowArc

The CangoAxes module also provides two global utility functions to format numbers in engineering notation which is scientific notation but the powers of ten are restricted to the preferred; nano, micro, milli, kilo, Mega, Giga etc. values. A JavaScript implementation of very useful 'sprintf' function is also included.

toEngFixed
toEngPrec
toEngNotation
toSciNotation
sprintf

Getting Started

The extension requires Cango canvas graphics library Version 19 or later. Save this file along with the CangoAxes file, then add the following lines to the web page header:

<script src="[directory path/]Cango-19v07-min.js"></script>
<script src="[directory path/]CangoAxes-8v00-min.js"></script>

Make sure that the CangoAxes file is loaded after the Cango file, as it adds methods to an existing Cango core. Application code can create Cango instances that they will have the additional methods available.


Cango methods

drawAxes

Syntax:

cgo.drawAxes(xmin, xmax, ymin, ymax [, options])

Description:

Draws a set of Cartesian coordinate (X, Y) axes.

Parameters:

xmin: Number - Minimum X axis value, the value of the left end of the X axis. Measured in the X axis world coordinates.

xmax: Number - Maximum X axis value, the value of the right end of the X axis. Measured in the X axis world coordinates.

ymin: Number - Minimum Y axis value, the value of the bottom end of the Y axis for RHC coordinates, top end for SVG style systems. Measured in the Y axis world coordinates.

ymax: Number - Maximum Y axis value, the value of the top end of the Y axis for RHC coordinates, bottom end for SVG style systems. Measured in the Y axis world coordinates.

options: Object - The values for the various optional properties may be passed as key-value pairs in this object (see Optional Properties below).

Optional Properties:

NameTypeRange
xOriginNumber
(world coordinates)
Point along X axis where Y axis will intersect.
yOriginNumber
(world coordinates)
Point along Y axis where X axis will intersect.
xOnlyBooleanIf set true, only the X axis is drawn. Some Y axis parameters are required for positioning etc but the Y axis is not drawn. Default value is false, both axes are drawn.
yOnlyBooleanIf set true, only the Y axis is drawn. Some X axis parameters are required for positioning etc but the X axis is not drawn. Default value is false, both axes are drawn.
xLabelStringText label for the X axis
yLabelStringText label for the Y axis
xUnitsStringA test string (usually a single character)showing the units represented along the X axis. The string is written in parentheses after the xLabel. The appropriate multiplier symbol (µ, m, k, etc) is automatically calculated and prepended to the Units symbol. If no units are specified the scientific notation for any multiplier is used.
yUnitsStringA test string (usually a single character)showing the units represented along the Y axis. The string is written in parentheses after the yLabel. The appropriate multiplier symbol (µ, m, k, etc) is automatically calculated and prepended to the yUnits symbol. If no units are specified the scientific notation for any multiplier is used.
xTickIntervalNumber
(world coordinates)
Distance between ticks along X axis. If undefined or set to "auto", a suitable tick interval will be calculated and the X axis ticked and labeled automatically. If set to 0 then no ticks are drawn. If a value is assigned it will be rounded to nearest 1, 2, 5 sequence value.
yTickIntervalNumber
(world coordinates)
Distance between ticks along Y axis. If undefined or set to "auto", a suitable tick interval will be calculated and the Y axis ticked and labeled automatically. If set to 0 then no ticks are drawn. If a value is assigned it will be rounded to nearest 1, 2, 5 sequence value.
tickDirectionString
("in" or "out")
Sets the direction of projection of the ticks on axes at the edges of the graph area. If set to "in" (default) the ticks project inward if set to "out" ticks project out. Outward projecting ticks are used for spectrograms and others displays filling the graph area.
xLabelIntervalNumber
(world coordinates)
Distance between labelled ticks which are along X axis. If undefined or set to "auto" every fifth tick along X axis will be labelled for sequences of 1 or 5 and every second tick for sequences of 2. If set to 0 no tick labels or units label will be drawn.
yLabelIntervalNumber
(world coordinates)
Distance between labelled ticks which are along Y axis. If undefined or set to "auto" every fifth tick along Y axis will be labelled for sequences of 1 or 5 and every second tick for sequences of 2. If set to 0 no tick labels or units label will be drawn.
fontFamilyStringCSS font family definitions (default set by Cango default fontFamily).
fontSizeNumber
(pixels)
Height of text characters (default set by Cango default fontSize).
fontWeightNumber100..900 (default set by Cango default fontWeight).
strokeColorStringColor to be used for axes and tick marks (default set by Cango default strokeColor).
fillColorStringColor to be used for text labels (default set by Cango default fillColor).

Examples:

function drawAxesTest(cvsID)
{
  var gc = new Cango(cvsID),
      xmin = -0.02, xmax = 0.025,
      ymin = -300, ymax = 600;

  gc.gridboxPadding(8);
  gc.setWorldCoordsRHC(xmin, ymin, xmax-xmin, ymax-ymin);
  gc.drawAxes(xmin, xmax, ymin, ymax, {
    xOrigin: 0,
    yOrigin: 0,
    xUnits:"m",
    yUnits:"V",
    xLabel:"Distance",
    yLabel:"Potential" });
}

Figure 1a. Simple example of 'drawAxes' method.

function drawJournalAxes(cvsID)
{
  var gc = new Cango(cvsID),
      xmin = 0, xmax = 0.025,
      ymin = 0, ymax = 600;

  gc.gridboxPadding(16, 10, 5, 5);
  gc.setWorldCoordsRHC(xmin, ymin, xmax-xmin, ymax-ymin);
  gc.drawAxes(xmin, xmax, ymin, ymax, {
    xOrigin: 0,
    yOrigin: 0,
    xUnits:"m",
    yUnits:"V",
    xLabel:"Distance",
    yLabel:"Potential",
    fontFamily:"Times" });
  gc.drawAxes(xmin, xmax, ymin, ymax, {
    xOrigin: xmax,
    yOnly:true,
    yLabelInterval: 0,
    fontColor: "blacK" });
  gc.drawAxes(xmin, xmax, ymin, ymax, {
    yOrigin: ymax,
    xOnly:true,
    xLabelInterval: 0 });
}
      

Figure 1b. Example of the 'drawAxes' method in the style used for scientific journals.

drawBoxAxes

Syntax:

cgo.drawBoxAxes(xmin, xmax, ymin, ymax [, options])

Description:

Draws a set of X, Y axes in the shape of a box.

Parameters:

xmin: Number - Minimum X axis value, the value of the left end of the X axis. Measured in the X axis world coordinates.

xmax: Number - Maximum X axis value, the value of the right end of the X axis. Measured in the X axis world coordinates.

ymin: Number - Minimum Y axis value, the value of the bottom end of the Y axis for RHC coordinates, top end for SVG style systems. Measured in the Y axis world coordinates.

ymax: Number - Maximum Y axis value, the value of the top end of the Y axis for RHC coordinates, bottom end for SVG style systems. Measured in the Y axis world coordinates.

options: Object - The values for the various optional properties may be passed as key-value pairs in this object (see Optional Properties below).

Optional Properties:

NameTypeRange
titleStringText of the label to be drawn at the top left of the axes box, normally used to describe the graphed data.
xUnitsStringText of the label to be drawn below the center of the X axis. The string is prepended with the xTickInterval value and the string "/div" is appended.
yUnitsStringText of the label to be drawn to the left of the center of the Y axis. The string is prepended with the yTickInterval value and string "/div" is drawn below the yUnits label.
xTickIntervalNumber
(world coordinates)
Distance between ticks along X axis. If omitted the tick interval will be automatic. If a value is supplied it will be rounded to nearest 1, 2, 5 sequence value.
yTickIntervalNumber
(world coordinates)
Distance between ticks along Y axis. If omitted the tick interval will default to 1/5th of the Y axis span. If a value is supplied it will be rounded to nearest 1, 2, 5 sequence value.
fontFamilyStringCSS font family definitions (default set by Cango default fontFamily).
fontSizeNumber
(pixels)
Height of text characters (default set by Cango default fontSize).
fontWeightNumber100..900 (default set by Cango default fontWeight)
strokeColorStringColor to be used for axes and tick marks (default value "#ffffff").
fillColorStringColor to be used for text labels (default value "#cccccc").
gridColorStringColor to be used for the grid drawn within the box, usually semi-transparent or dashed (default value "rgba(255,255,255,0.2)").

Example:

function drawBoxAxesTest(cvsID)
{
  var g = new Cango(cvsID),
      data = [],
      i;

  g.fillGridbox("#303a30");
  g.gridboxPadding(12, 8, 3, 8);
  g.setWorldCoordsRHC(0, -10, 1200, 20);

  g.drawBoxAxes(0, 1200, -10, 10, {
    xUnits:"Hz", 
    yUnits:"dB", 
    title:"REAL"});
  for (i=0; i<=200; i++)
  {
    data.push(i*6, 5*Math.sin(i/6));
  }
  g.drawPath(data, {strokeColor:'#c0e0ff'});
}

Figure 2. Simple example of 'drawBoxAxes' method.

drawArrow

Syntax:

cgo.drawArrow(headX, headY [, options]);

Description:

Draws a straight arrow shape. The arrow starting at world coordinates 0, 0 unless the options parameter has properties 'x' and/or 'y' in which case the arrow will be drawn from these x,y coordinates. The arrow head will end at the point with world coordinates (headX, headY). An arrow head is draw at the end point. The arrow shaft width mat be set in either pixels or world coordinates and head size can be adjusted by specifying a head size scale factor relative to the shaft width.

The arrow is a Shape object so it can be drawn with different colored border, a drop shadow or any of the other properties supported by Shape objects.

NOTE: The arrow shape is always drawn with the 'iso' property set true to preserve the arrow shape when independent X and Y world coordinate scaling is used.

Parameters:

headX, headY: Numbers - X and Y coordinates of the tip of the arrow head. Measured in the world coordinates.

options:Object - The values for the various optional properties may be passed as key-value pairs in this object (see Options Properties below).

Optional Properties:

Property NameTypeDescription
xNumber
(World Coordinates)
X coordinates of the drawing origin, start of arrow shaft (default = 0).
yNumber
(World Coordinates)
Y coordinates of the drawing origin, start of arrow shaft (default = 0).
shaftWidthNumber
(pixels)
Width of the arrow shaft.
shaftWidthWCNumber
(world coordinates)
Width of the arrow shaft, this value takes precedence over shaft width set in pixels by 'shaftWidth' property.
headSizeNumberRelative size of the head. Length of head is ~headSize*shaftWidth (default = 4).
fillColorCSS Color or gradientsee Colors

The other Shape object optional properties are also supported:

  • scl
  • degs
  • border
  • strokeColor
  • lineWidthWC
  • lineWidth
  • dashed
  • dashOffset
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor

(see Shape.setProperty method for more details).

Example:

function drawArrows(cvsID)
{
  var gc = new Cango(cvsID),
      xmin = -15, xmax = 25,
      ymin = 0, ymax = 4;

  gc.gridboxPadding(10, 8, 2, 8);
  gc.setWorldCoordsRHC(xmin, ymin, xmax-xmin, ymax-ymin);
  gc.drawAxes(xmin, xmax, ymin, ymax, {xOrigin:0, yOrigin:0, strokeColor:'gray'});

  // test straight arrow
  gc.drawArrow(20, 3, {
    x:5, y:1,
    shaftWidthWC:2,
    headSize:4,
    fillColor:'red',
    border:true,
    strokeColor:'blue',
    lineWidth:2});

  gc.drawArrow(-10, 4, {
    x:0, y:1,
    shaftWidth: 8,
    fillColor:'green'});
}

Figure 5. Simple example of 'drawArrow' method.

drawArrowArc

Syntax:

cgo.drawArrowArc(radius, startAngle, stopAngle, options);

Description:

Draws a curved arrow whose shape is a circular arc of radius 'radius' starting at the angle 'startAngle' from the X axis and finishing at 'stopAngle'. An arrow head is drawn at the end with its tip at radius 'radius' and angle 'stopAngle'. The drawing origin will be at the center of the circular arc. If options properties 'x' and/or 'y' are specified then the center of the arc will be drawn at world coordinates x,y otherwise the center will be drawn at world coordinates 0,0.

NOTE: The arrow shape is always drawn with the 'iso' property set true to preserve the arrow shape when independent X and Y world coordinate scaling is used.

Parameters:

radius: Number - The radius of the circular arc formed by the arrow shaft. Measured in the world coordinates.

startAngle: Number - The angle at which the arrow arc starts . Measured in degrees from X axis.

stopAngle: Number - The angle at which the arrow arc stops. Measured in degrees from X axis.

options: Object - The values for the various optional properties may be passed as key-value pairs in this object (see Options Properties below).

Optional Properties:

Property NameTypeDescription
xNumber
(World Coordinates)
X coordinates of the drawing origin, start of arrow shaft (default = 0).
yNumber
(World Coordinates)
Y coordinates of the drawing origin, start of arrow shaft (default = 0).
shaftWidthNumber
(pixels)
Width of the arrow shaft.
shaftWidthWCNumber
(world coordinates)
Width of the arrow shaft, this value takes precedence over shaft width set in pixels by 'shaftWidth' property.
headSizeNumberRelative size of the head. Length of head is ~headSize*shaftWidth (default = 4).
clockwiseBooleanIf true the arrow sweeps clockwise from startAngle to stopAngle, if false it sweeps counter-clockwise
fillColorCSS Color or gradientsee Colors

The other Shape object optional properties are also supported:

  • scl
  • degs
  • border
  • strokeColor
  • lineWidthWC
  • lineWidth
  • dashed
  • dashOffset
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor

(see Shape.setProperty method for more details).

Example:

function arrowArcDemo(cvsID)
{
  var xmin = -15, xmax = 25,
      ymin = -4, ymax = 4;

  cgo = new Cango(cvsID),
  cgo.clearCanvas("beige");
  cgo.gridboxPadding(15, 2, 15, 2);  // data area, units are % of canvas width

  cgo.setWorldCoordsRHC(xmin, ymin, xmax-xmin, ymax-ymin);
  cgo.drawAxes(xmin, xmax, ymin, ymax, {
    xOrigin: 0, yOrigin: 0,
    xLabel:"X", yLabel:"Y",
    fontSize: 10 });

  cgo.drawArrowArc(8, 40, 280, {
    x:-10,
    y:-2,
    clockwise:true,
    shaftWidth:4,
    fillColor:'black'});
  cgo.drawArrowArc(12, 280, 40, {
    clockwise:false,
    shaftWidth:8,
    fillColor:'green',
    shadowOffsetX:0.50,
    shadowOffsetY:-0.1,
    shadowBlur:0.5,
    shadowColor:'gray'});
  cgo.drawArrowArc(15, 20, 156, {
    clockwise: false,
    shaftWidthWC: 1.7,
    fillColor: 'steelblue',
    border:true,
    strokeColor:'red'});
}

Figure 6. Simple example of 'drawArrow' method.


Global utilities added

toEngFixed

Syntax:

var str = toEngFixed(val, decPlaces);

Description:

Converts the value val to engineering notation, i.e. mantissa and exponent where the exponent is restricted to values that are multiples of 1000. The string returned denotes the exponent by the standard single letter values µ, m, k, M, G etc. All mantissa values are expressed in the range 1 to 1000 with the number of decimal places set by the decPlaces parameter. The result is rounded to the decPlaces decimal places with no trailing zeroes are removed.

Parameters:

val:Number - The value to be formatted.

decPlaces:Number - the number of decimal places in the mantissa.

Returns:

String - The formatted string version of val.

Examples:

toEngFixed(1200.0, 3) returns "1.200k".
toEngFixed(0.012345, 2) returns "12.35m".
toEngPrec

Syntax:

var str = toEngPrec(val, sigFigs, showPlus);

Description:

Converts the value val to engineering notation, i.e. mantissa and exponent where the exponent is restricted to values that are multiples of 1000. The result is then rounded to a precision of sigFigs significant figures which must be 3 or greater. The string returned denotes the exponent by the standard single letter values p, n, µ, m, k, M, G. All mantissa values are expressed in the range 1 to <1000. The returned string has a fixed length regardless of whether the number is negative or requires a decimal radix.

Parameters:

val: Number - The value to be formatted.

sigFigs: Number - the number of significant figures in the mantissa. Default value is 3

showPlus: Boolean - if evaluating true and the number is positive, a "+" sign is prepended to the return string.

Returns:

String - The formatted string version of val.

Examples:

toEngPrec(1234.5678, 5)   returns  " 1.2346k".
toEngPrec(-1234.5678, 5)  returns  "-1.2346k".
toEngPrec(0.012345, 3)       returns " 12.3m".
toEngPrec(0.012345, 3, true) returns "+12.3m".
toEngPrec(123.45, 3)         returns "  123 ".
toEngNotation

Syntax:

var obj = toEngNotation(val, exponent);

Description:

Converts the value val to engineering notation, i.e. mantissa and exponent where the exponent is restricted to values that are multiples of 1000. The result is then rounded to 2 decimal places (suitable for labelling graphs). An object is returned with the numeric and string versions of the value and exponent as properties. The optional parameter 'exponent' allows a preset value of the exponent to be used in the value conversion. The string version of the exponent returned will be the standard single letter values p, n, µ, m, k, M, G. All mantissa values are expressed in the range 1 to <1000.

Parameters:

val: Number - The value to be formatted.

exponent: Number - An optional pre-calculated exponent to be used in the conversion. If undefined or not a multiple of 3 the exponent is ignored and a new exponent calculated.

Returns:

Object - The formatted numeric and string versions of val converted to engineering notation. The property names are: {man: , exp, manStr: , expStr}.

Examples:

toEngNotation(1234.5678)  returns { man: 1.23, manStr: "1.23", exp: 3, expStr: "k" }.
toEngNotation(0.012345)    returns { man: 12.35, manStr: "12.35", exp: -3, expStr: "m" }.
toEngNotation(0.012345, 0) returns { man: 0.01, manStr: "0.01", exp: 0, expStr: "" }.
toEngNotation(123.45)      returns { man: 123.45, manStr: "123.45", exp: 0, expStr: "" }.
If 'exponent' parameter is not a multiple of 3, it is ignored eg.
toEngNotation(1234.5678, 2) returns { man: 1.23, manStr: "1.23", exp: 3, expStr: "k" } 
toSciNotation

Syntax:

var obj = toSciNotation(val [, exponent]);

Description:

Converts the value val to scientific notation, i.e. mantissa and exponent where the exponent is a power of 10. The result is then rounded to 2 decimal places (suitable for labelling graphs). An object is returned with the numeric and string versions of the value and exponent as properties. The optional parameter 'exponent' allows a preset value of the exponent to be used in the value conversion.

Parameters:

val: Number - The value to be formatted.

exponent: Number - An optional pre-calculated exponent to be used in the conversion. If undefined the exponent is calculated.

Returns:

Object - The formatted numeric and string versions of val converted to scientific notation. The property names are: {man: , manStr: , exp, expStr}.

Examples:

toSciNotation(12345.678)       returns { man: 1.23, manStr: "1.23", exp: 4, expStr: "4" }.
toSciNotation(-12.345678)      returns { man: -1.23, manStr: "-1.23", exp: 1, expStr: "1" }.
toSciNotation(0.012345, 0)     returns { man: 0.01, manStr: "0.01", exp: 0, expStr: "0" }.
toSciNotation(0.000012345)     returns { man: 1.23, manStr: "1.23", exp: -5, expStr: "-5" }.
toSciNotation(0.000012345, -4) returns { man: 0.12, manStr: "0.12", exp: -4, expStr: "-4" }.
sprintf

Syntax:

var str = sprintf(format, arg1, arg2 ...);

Description:

This JavaScript implementation of the 'sprintf' utility was originally written by Ash Searle (2007/03/printf-sprintf/) and enhanced by Kevin van Zonneveld (http://kevin.vanzonneveld.net).

The 'format' string is composed of ordinary characters (excluding %) and optional conversion specifications. Ordinary characters are copied directly to the result. Each conversion specification consists of a percent sign (%), followed by one or more of these elements, flags, width, precision and type specifier. Each conversion specifications takes an argument in turn from those following 'format' and converts it a substring which replaces the specifier in the output.

Parameters:

format:String - Which may contain characters which are returned unaltered, and conversion specifiers. The conversion specifier sub-string should be in the form:

  %[flags][width][.precision]type_specifier

The optional flags are shown in the table below.

flagsdescription
-Left-justify within the given field width; Right justification is the default (see width sub-specifier).
+Forces the result to be preceded by a '+' or '-' sign. By default, only negative numbers are preceded with a - sign.
(space)If no sign is going to be written, a blank space is inserted before the value.
#Used with o, x or X specifiers. The value is preceded by a 0, 0x or 0X respectively, for values different than zero.
Used with a, A, e, E, f, F, g or G it forces the written output to contain a decimal point even if no more digits follow. By default, if no digits follow, no decimal point is written.
0Left-pads the number with zeroes (0) instead of spaces when padding is specified (see width sub-specifier).

The optional width specifier is a number that says how many characters (minimum) this conversion should result in.

An optional precision specifier in the form of a period ('.') followed by an optional decimal digit string that says how many decimal digits should be displayed for floating-point numbers. When using this specifier on a string, it acts as a cutoff point, setting a maximum character limit to the string.

The type specifier defines what type the argument data should be treated as. Possible types are shown in the table below.

type specifierOutputExample
d or iSigned decimal integer392
uUnsigned decimal integer7235
oUnsigned octal610
xUnsigned hexadecimal integer7fa
XUnsigned hexadecimal integer (uppercase)7FA
f or FDecimal floating point392.65
eScientific notation (mantissa/exponent), lowercase3.9265e+2
EScientific notation (mantissa/exponent), uppercase3.9265E+2
gUse the shortest representation: %e or %f392.65
GUse the shortest representation: %E or %F392.65
cCharactera
sString of characterssample
%%% will write a single % to the string.%

arg1, arg2, . . .  :mixed types - The parameters to be converted to strings and substituted for conversion specifiers.

Returns:

String - The formatted version of format with specifiers replaced with arguments in the order passed.

Examples:

var str = sprintf("pi = %4.2f", Math.PI); //  returns "pi = 3.14".