Show Nav

Custom Modules

Overview

There are two different types of modules in ZingChart, chart type modules, and plugin modules. Chart type modules are initialized by the value of the "type" attribute in the graph object, and plugin modules are initialized through the use of the modules option in the zingchart.render() method.

With each of these custom module types, the idea is similar: modify the original JSON, add event listeners, and define options for your custom module.

Define a module using the defineModule() method:

zingchart.defineModule(String name, String type, Function callback);

Parameters

Parameter Type Values Details
name String N/A Required. User defined string to use as the name for the module.
type String "chart"|"plugin" Required. Determines the type of the module. A module of type "chart" will be used when the value of a chart object's "type" attribute matches that of the module name. A module of type "plugin" will be used when there is an object within the chart JSON that matches the plugin name.
callback Function N/A Required. User defined function that is used to manipulate the original chart JSON, define options, and add event listeners. This function receives the original chart JSON of the chart using the custom module. This function must return the modified version of the original chart object, or an entirely new object altogether.

Module definitions can be placed within your HTML page, or in a separate zingchart-[MODULE NAME].min.js file.

Defining a Chart Type Module

To define a module that will serve as a standalone chart type, set the defineModule type parameter to "chart". Be sure to pass a single argument to your function. This argument will allow you to gain access to the chart configuration object that makes use of your custom module.

Example

zingchart.defineModule("hello-world", "chart", function(originalJson){
    /** 
    *   Perform JSON manipulation on the originalJson object, define options, 
    *   and add event listeners here.
    */

    return originalJson; // Modified version of originalJson
});

When defined in this way, any chart object that uses the module name as the value for the "type" attribute will apply this module's logic.

zingchart.render({
    id: 'myChart',
    height: 400,
    width: 600,
    data: {
        "type":"hello-world"
    }
});

Click to here to jump to Defining Chart Type Module Options.

Defining a Plugin Module

To define a module that will serve as a plugin, set the defineModule type parameter to "plugin". Be sure to pass a single argument to your function. This argument will allow you to gain access to the chart configuration object that makes use of your custom module.

Example

zingchart.defineModule("hello-world", "plugin", function(originalJson){
    /** 
    *   Perform JSON manipulation on the originalJson object, define options, 
    *   and add event listeners here.
    */

    return originalJson; // Modified version of originalJson
});

Plugin modules must be explicitly loaded using the modules option in the render method. When defined in this way, any chart that contains an object of the plugin name will apply this module's logic.

zingchart.render({
    id: 'myChart',
    height: 400,
    width: 600,
    modules: 'hello-world', // Load the module
    data: {
        "type":"bar",
        "hello-world":{
        
        }
    }
});

Click to here to jump to Defining Plugin Module Options.

JSON Manipulation

For both chart type modules and plugin modules, JSON manipulation is handled the same way. In the example below, originalJson is the chart object containing a chart with the matching "type" attribute (since this is a chart type module). If this were a plugin module, originalJson would be the chart object containing the "hello-world" object in the top level of the chart JSON. Perform your JSON manipulation on the originalJson object, taking the steps necessary to prevent data obliteration!

Chart Type Example

zingchart.defineModule("hello-world", "chart", function(originalJson){
    /* Create our hello world label */
    var helloWorldLabel = {
        "text": "Hello, world!",
        "id": "label1",
        "height": "60%",
        "width": "80%",
        "x": "10%",
        "y": "20%"
    };
    
    /* 
    *   The ?: ternary operation is used here to check for existing labels in the originalJson object. 
    *   If a labels array exists, the label is pushed into it,
    *   otherwise, it is placed into a new array.
    */
    originalJson["labels"] 
        ? originalJson["labels"].push(helloWorldLabel) 
        : originalJson["labels"] = [helloWorldLabel];

    return originalJson;
});

If you are using a graphset array with multiple chart objects, the defineModule method will automatically loop over each object in the array, applying your module's logic to only the chart objects that use the custom module.

Defining Chart Type Module Options

While you can define options in a number of ways, we recommend placing options for a chart type module in an "options" object at the graph level. For example,

 {
    "type": "hello-world",
    "options": {
        "universe": true
    }
 }

Now to define our boolean "universe" attribute in our chart type module definition:

zingchart.defineModule("hello-world", "chart", function(originalJson){
    /* Previously shown code omitted for brevity */
    
    /* Check for the existence of the options object */
    if (originalJson["options"]){
    
        /* It exists! Instantiate oOptions as the object containing our custom options. */
        var optionsObj = originalJson["options"];
        
        /* Check for "universe": true, find our label and modify it if true */
        if (optionsObj["universe"]){
            for (var n = 0;n < originalJson["labels"].length;n++){
                if (originalJson["labels"][n]["id"] == "label1"){
                    originalJson["labels"][n] = "Hello, UNIVERSE!"
                }
            }
        }
    }

    return originalJson;
});

Defining Plugin Module Options

For a plugin module, check the plugin object for options, instead of checking for an options object:

zingchart.defineModule("hello-world", "plugin", function(originalJson){
    /* Previously shown code omitted for brevity */
    
    /* Instantiate oOptions as the plugin object */
    var optionsObj = originalJson["hello-world"];
        
        /* Check for "universe": true, find our label and modify it if true */
        if (optionsObj["universe"]){
            for (var n = 0;n < originalJson["labels"].length;n++){
                if (originalJson["labels"][n]["id"] == "label1"){
                    originalJson["labels"][n] = "Hello, UNIVERSE!"
                }
            }
        }
    }

    return originalJson;
});

Adding Event Listeners

If you want to make your module interactive, event listeners are a must. For example, if you added shape objects for some kind of toolbar during the JSON manipulation phase, you'll need to set up event listeners to allow the user to interact with your toolbar. Here, we add a label_click event listener to our module:

zingchart.defineModule("hello-world", "chart", function(originalJson){
    /* Previously shown code omitted for brevity */
    
    zingchart.bind(null, 'label_click', function(chartObj){
        if (chartObj.graphid == "helloworld0"){
            console.log('What? What do you want?');
        }
    });

    return originalJson;
});

Notice that comparison between chartObj's graphid value and "helloworld0"? The defineModule() method generates an ID for a chart type module, using the name of the module itself (with hyphens removed) and the index of the chart object in the graphset. So, if you have a module called "my-first-module" at index 0 in your graphset (or it's just a lone chart object not in a graphset), defineModule() will generate and apply an ID called "myfirstmodule0". You can use this to increase event specificity in your charts, as we have done above.

Minifying Your Script

We here at ZingChart use UglifyJS for minification of the library.

To use as a command line app, install using NPM:

npm install uglify-js -g

Command line usage of UglifyJS usage is as follows:

uglifyjs [input file] [options]

If the defineModule code is placed in a standalone file instead of directly in the HTML document, example command for compression of our custom module, outputting to a separate file (UglifyJS defaults to STDOUT), would be as follows:

uglifyjs zingchart-hello-world.js --compress --output zingchart-hello-world.min.js

More information on UglifyJS can be found on GitHub.

Examples

The following two demos may look identical on the surface, but if you dive into the code used to create each one of these custom modules, you'll soon discover the difference between the two.

Custom Chart Type Module

Loading...
Result
HTML
JavaScript
CSS
A beautiful chart

Custom Plugin Module

Loading...
Result
HTML
JavaScript
CSS
A beautiful chart

Custom Zoom Module

Loading...
Result
HTML
JavaScript
CSS
A beautiful chart