License Release NPM

An interactive Javascript Plotting Boilerplate

For plotting visual 2D data with Javascript on HTML canvas (in 2d-context) or SVG nodes.

logo

This is a simple collection of useful functions, methods, classes, algorithms and concepts which I often use for the visualization of 2D geometries. Basic features are

The compressed library has 135kb.

Install the package via npm

   # Installs the package
   $ npm i plotboilerplate

The HTML file

For a full example see main-dist.html :

<canvas id="my-canvas"> Your browser does not support the canvas tag. </canvas>

The element canvas will be used to draw on.

The javascript

var pb = new PlotBoilerplate({
  canvas: document.getElementById("my-canvas"),
  fullSize: true
});

Alternative with SVG elements

Use SVG elements instead of canvas:

<svg id="my-svg"></svg>

And pass the SVG element:

var pb = new PlotBoilerplate({
  canvas: document.getElementById("my-svg"),
  fullSize: true
});

Add elements to your canvas

// Create two points:
//   The origin is at the visual center by default.
var pointA = new Vertex(-100, -100);
var pointB = new Vertex(100, 100);
pb.add(new Line(pointA, pointB));

// When point A is moved by the user
//   then move point B in the opposite direction
pointA.listeners.addDragListener(function (e) {
  pointB.sub(e.params.dragAmount);
  pb.redraw();
});

// and when point B is moved
//   then move point A
pointB.listeners.addDragListener(function (e) {
  pointA.sub(e.params.dragAmount);
  pb.redraw();
});

Typescript

// Usage with Typescript could look like this
import { PlotBoilerplate, Vertex, Line } from "plotboilerplate";

globalThis.addEventListener("load", () => {
  const pointA: Vertex = new Vertex(100, -100);
  const pointB: Vertex = new Vertex(-100, 100);
  console.log(pointA, pointB);

  const line: Line = new Line(pointA, pointB);

  const pb: PlotBoilerplate = new PlotBoilerplate({
    canvas: document.getElementById("my-canvas"),
    fullSize: true
  });

  pb.add(line);
});

For a guide of how to Getting Started click here.

A full working demo repository about the Usage with Typescript is here.

Codepen Demos

Basic Setup in a Codepen.io demo

Screenshot

Simple Demo

And the simple demo is here

API

See API Documentation for details.

Screenshot

Current demo

See the demo

Examples and Demos

Examples and Demos

Initialization parameters

Name Type Default Description
canvas HTMLCanvasElement | SVGElement | string null The canvas or its query selector string (required).
fullsize boolean true If true, then the canvas will always claim tha max available screen size.
fitToParent boolean true If true, then the canvas will alway claim the max available parent container size.
scaleX number 1.0 The initial horizontal zoom. Default is 1.0.
scaleY number 1.0 The initial vertical zoom. Default is 1.0.
offsetX number 0.0 The initial offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.
offsetY number 0.0 The initial offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.
drawGrid boolean true Specifies if the raster should be drawn.
rasterScaleX number 1.0 Define the default horizontal raster scale.
rasterScaleY number 1.0 Define the default vertical raster scale.
rasterGrid boolean true If set to true the background grid will be drawn rastered.
rasterAdjustFactor number 2.0 The exponential limit for wrapping down the grid. (2.0 means: halve the grid each 2.0*n zoom step).
drawOrigin boolean false Draw a crosshair at (0,0).
autoAdjustOffset boolean true When set to true then the origin of the XY plane will be re-adjusted automatically (see the params offsetAdjust{X,Y}Percent for more).
offsetAdjustXPercent number 50 The x- and y- fallback position for the origin after resizing the canvas.
offsetAdjustYPercent number 50 The x- and y- fallback position for the origin after resizing the canvas.
defaultCanvasWidth number 1024 The canvas size fallback if no automatic resizing is switched on.
defaultCanvasHeight number 768 The canvas size fallback if no automatic resizing is switched on.
canvasWidthFactor number 1.0 Two scaling factors (width and height) upon the canvas size. In combination with cssScale{X,Y} this can be used to obtain sub pixel resolutions for retina displays.
canvasHeightFactor number 1.0 Two scaling factors (width and height) upon the canvas size. In combination with cssScale{X,Y} this can be used to obtain sub pixel resolutions for retina displays.
cssScaleX number 1.0 Visually resize the canvas using CSS transforms (scale x).
cssScaleY number 1.0 Visually resize the canvas using CSS transforms (scale y).
cssUniformScale boolean 1.0 If set to true only cssScaleX applies for both dimensions.
autoDetectRetina boolean true When set to true (default) the canvas will try to use the display’s pixel ratio.
backgroundColor string #ffffff A background color (CSS string) for the canvas.
redrawOnResize boolean true Switch auto-redrawing on resize on/off (some applications might want to prevent automatic redrawing to avoid data loss from the drae buffer).
drawBezierHandleLines boolean true Indicates if Bézier curve handle points should be drawn.
drawBezierHandlePoints boolean true Indicates if Bézier curve handle points should be drawn.
preClear function null A callback function that will be triggered just before the draw function clears the canvas (before anything else was drawn).
preDraw function null A callback function that will be triggered just before the draw function starts.
postDraw function null A callback function that will be triggered right after the drawing process finished.
enableMouse boolean true Indicates if the application should handle touch events for you.
enableTouch boolean true Indicates if the application should handle touch events for you.
enableKeys boolean true Indicates if the application should handle key events for you.
enableMouseWheel boolean true Indicates if the application should handle mouse wheelevents for you.
enableSVGExport boolean true Indicates if the SVG export should be enabled (default is true).
enableGL boolean false [Experimental] Indicates if the application should use the experimental WebGL features.

Example

var pb = new PlotBoilerplate({
  // HTMLCanvasElement | SVGElement | string
  //   Your canvas element in the DOM (required).
  canvas: document.getElementById("my-canvas"),

  // boolean
  //   If set to true the canvas will gain full window size.
  fullSize: true,

  // boolean
  //   If set to true the canvas will gain the size of its parent
  //   container.
  // @overrides fullSize
  fitToParent: true,

  // float
  //   The initial zoom. Default is 1.0.
  scaleX: 1.0,
  scaleY: 1.0,

  // float
  //   The initial offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.
  offsetX: 0.0,
  offsetY: 0.0,

  // Specifies if the raster should be drawn.
  drawGrid: true,

  // If set to true the background grid will be drawn rastered.
  rasterGrid: true,

  // float
  //    The exponential limit for wrapping down the grid.
  //    (2.0 means: halve the grid each 2.0*n zoom step).
  rasterAdjustFactor: 2.0,

  // Draw a crosshair at (0,0).
  drawOrigin: false,

  // boolean
  //   When set to true then the origin of the XY plane will
  //   be re-adjusted automatically (see the params
  //    offsetAdjust{X,Y}Percent for more).
  autoAdjustOffset: true,
  // float
  //   The x- and y- fallback position for the origin after
  //   resizing the canvas.
  offsetAdjustXPercent: 50,
  offsetAdjustYPercent: 50,

  // int
  //   The canvas size fallback if no automatic resizing
  //   is switched on.
  defaultCanvasWidth: 1024,
  defaultCanvasHeight: 768,

  // float
  //   Two scaling factors (width and height) upon the canvas size.
  //   In combination with cssScale{X,Y} this can be used to obtain
  //   sub pixel resolutions for retina displays.
  canvasWidthFactor: 1.0,
  canvasHeightFactor: 1.0,

  // float
  //   Visually resize the canvas using CSS transforms (scale).
  cssScaleX: 1.0,
  cssScaleY: 1.0,

  // boolean
  //   If set to true only cssScaleX applies for both dimensions.
  cssUniformScale: true,

  // boolean
  //   When set to true (default) the canvas will try to use the display's pixel ratio.
  autoDetectRetina: true,

  // string
  //   A background color (CSS string) for the canvas.
  backgroundColor: "#ffffff",

  // boolean
  //   Switch auto-redrawing on resize on/off (some applications
  //   might want to prevent automatic redrawing to avoid data
  //   loss from the drae buffer).
  redrawOnResize: true,

  // boolean
  //   Indicates if Bézier curve handles should be drawn (used for
  //   editors, no required in pure visualizations).
  drawBezierHandleLines: true,

  // boolean
  //   Indicates if Bézier curve handle points should be drawn.
  drawBezierHandlePoints: true,

  // function
  //   A callback function that will be triggered just before the
  //   draw function clears the canvas (before anything else was drawn).
  preClear: function () {
    console.log("before clearing the canvas on redraw.");
  },

  // function
  //   A callback function that will be triggered just before the
  //   draw function starts.
  preDraw: function (draw, fill) {
    console.log("after clearing and before drawing.");
  },

  // function
  //   A callback function that will be triggered right after the
  //   drawing process finished.
  postDraw: function (draw, fill) {
    console.log("after drawing.");
  },

  // boolean
  //   Indicates if the application should handle mouse events for you.

  enableMouse: true,
  // boolean
  //   Indicates if the application should handle touch events for you.
  enableTouch: true,

  // boolean
  //   Indicates if the application should handle key events for you.
  enableKeys: true,

  // boolean
  //   Indicates if the application should handle mouse wheelevents for you.
  enableMouseWheel: true,

  // boolean (default true)
  //    Use this to disable panning completely.
  enablePan: true,

  // boolean (default true)
  //    Use this to disable zooming completely.
  enableZoom: true,

  // Indicates if the SVG export should be enabled (default is true).
  enableSVGExport: true,

  // boolean
  //   Indicates if the application should use the experimental WebGL features.
  enableGL: false
});

Events

The Vertex class has basic drag event support:

var vert = new Vertex(100, 100);
vert.listeners.addDragListener(function (e) {
  // e is of type Event.
  // You are encouraged to use the values in the object e.params
  console.log("vertex was dragged by: ", "x=" + e.params.dragAmount.x, "y=" + e.params.dragAmount.y);
});

The e.params object

 {
  // The canvas that fired the event.
  element : [HTMLElement],

  // The event name.
  //   Default: 'drag'
  name : string,

  // The current drag position.
  pos : { x : number, y : number },

  // A mouse button indicator (if mouse event).
  //    0=left, 1=middle, 2=right
  button : number,

  // A flag indicating if event comes from left mouse button.
  leftButton : boolean,

  // A flag indicating if event comes from middle mouse button.
  middleButton : boolean,

  // A flag indicating if event comes from right mouse button.
  rightButton : boolean,

  // A mouse-down-position: position where the dragging
  //   started. This will not change during one drag process.
  mouseDownPos : { x : number, y : number },

  // The most recent drag position (position before
  //   current drag step).
  draggedFrom : { x : number, y : number },

  // True if this is a drag event (nothing else available the moment).
  wasDragged : boolean,

  // The x-y-amount of the current drag step.
  //   This is the difference between the recent drag step
  //   and the actual drag position.
  dragAmount : { x : number, y : number }
 }
Name Type Example value Description
element HTMLCanvasElement [HTMLCanvasElement] The canvas that fired the event.
name string drag The event name (default is ‘drag’).
pos position { x : 20, y : 50 } The current drag position.
button number 0 A mouse button indicator (if mouse event). 0=left, 1=middle, 2=right
leftButton boolean true A flag indicating if event comes from left mouse button.
middleButton boolean false A flag indicating if event comes from middle mouse button.
rightButton boolean false A flag indicating if event comes from right mouse button.
mouseDownPos position { x : 0, y : 20 } A mouse-down-position: position where the dragging started. This will not change during one drag process.
draggedFrom position { x : 10, y : -5 } The most recent drag position (position before current drag step).
wasDragged boolean true True if this is a drag event (nothing else available at the moment).
dragAmount position { x : 100, y : 34 } The x-y-amount of the current drag step. This is the difference between the recent drag step and the actual drag position.

Mouse, Keyboard and Touch interaction

  • [SHIFT] + [Click] : Select/Deselect vertex
  • [Y] + [Click]: Toggle Bézier auto-adjustment for clicked bézier path point
  • [ALT or SPACE] + [Mousedown] + [Drag] : Pan the area
  • [Mousewheel-up] : Zoom in
  • [Mousewheel-down] : Zoom out
  • Touch & move (1 finger): Move item
  • Touch & move (2 fingers): Pan the area
  • Touch & pinch: Zoom in/out

Custom keyboard events

new KeyHandler({ trackAll: true })
  .down("enter", function () {
    console.log("ENTER was hit.");
  })
  .press("enter", function () {
    console.log("ENTER was pressed.");
  })
  .up("enter", function () {
    console.log("ENTER was released.");
  })
  .down("e", function () {
    console.log("e was hit. shift is pressed?", keyHandler.isDown("shift"));
  })
  .up("spacebar", function () {
    console.log("spacebar was released.");
  });

For a list of all supported key codes see Full list of supported key codes.

Custom mouse event

new MouseHandler(document.getElementById("mycanvas"))
  .drag(function (e) {
    console.log("Mouse dragged: " + JSON.stringify(e));
    if (e.params.leftMouse);
    else if (e.params.rightMouse);
  })
  .move(function (e) {
    console.log("Mouse moved: " + JSON.stringify(e.params));
  })
  .up(function (e) {
    console.log("Mouse up. Was dragged?", e.params.wasDragged);
  })
  .down(function (e) {
    console.log("Mouse down.");
  })
  .click(function (e) {
    console.log("Click.");
  })
  .wheel(function (e) {
    console.log("Wheel. delta=" + e.deltaY);
  });

Build the package

Compile and build howto

Browsers support

IE / Edge
IE / Edge
Firefox
Firefox
Chrome
Chrome
iOS Safari
iOS Safari
IE11 & Edge latest latest latest

Credits

Todos

What needs to be done

Known bugs

  • SVG resizing does not work in Firefox (aspect ratio is always kept, even if clip box changes). Please use PNGs until this is fixed.
  • The BBTree.iterator() fails if the tree is empty! (Demos)
  • The minifid BBTree and BBTreeCollection files do not export anything. The un-minified does. Why that?
  • Arcs and ellipses break when non-uniform scaling (scalex!=scaley) is applied. Convert them to Bézier curves before drawing.
  • Currently no more known. Please report bugs.

Oh look, a cat ᓚᘏᗢ

Basics

How to use the basic classes

Changelog

View changelog