Tutorials
Getting started
Chart interface
Web components
Chart internals
Data integration
Customization
Frameworks and bundlers
Mobile development
Trading
Time Span Events
Term structures
ScriptIQ
Troubleshooting
Glossary
Reference
JSFiddles

Chart Sharing

ChartIQ's CIQ.Share class enables you to easily build functionality that lets your end users share images of their charts.

Chart images can be shared from a simple button control using default image parameters or from a preferences dialog box that enables customization of the image.

Sharing a chart consists of two steps:

  1. Rendering an image of the chart
  2. Uploading the image to a server to be shared

CIQ.Share.createImage creates the image of the chart. CIQ.Share.uploadImage uploads the image to a server. CIQ.Share.uploadImage is typically called in the function passed to the cb (callback) parameter of CIQ.Share.createImage.

Note: This decoupled functionality gives you the ability to create a preferences dialog box so images can be customized before they're uploaded.

The CIQ.Share.shareChart function wraps CIQ.Share.createImage and CIQ.Share.uploadImage, enabling rendering and uploading of an image in a single function call.

Here's how the cq-share-dialog web component uses the CIQ.Share functions to implement chart sharing:

// Temporarily disable menu bindings.
CIQ.UI.bypassBindings = true;

CIQ.Share.createImage(
    stx,
    {
        // A CSS selector list of DOM elements to be hidden while an image of the chart is created.
        // DOM elements selected by "cq-comparison-add-label" and ".chartSize" are hidden by default.
        hide: [
            ".stx_chart_controls",
            ".stx-btn-panel",
            ".stx_jump_today",
            ".stx-baseline-handle",
            ".ciq-edit",
            ".ciq-close",
            "cq-marker-label"
        ]
    },
    function (data) {
        // Re-enable menu bindings.
        CIQ.UI.bypassBindings = false;
        var id = CIQ.uniqueID();
        var host = "https://share.chartiq.com";
        var startOffset = stx.getStartDateOffset();
        var metaData = {
            layout: stx.exportLayout(),
            drawings: stx.exportDrawings(),
            xOffset: startOffset,
            startDate: stx.chart.dataSegment[startOffset].Date,
            endDate: stx.chart.dataSegment[stx.chart.dataSegment.length - 1].Date,
            id: id,
            symbol: stx.chart.symbol
        };
        var url = host + "/upload/" + id;
        var payload = { id: id, image: data, config: metaData };
        self.setState("share-upload");
        CIQ.Share.uploadImage(data, url, payload, function (err, response) {
            self.setState("share-copy");
            if (err !== null) {
                CIQ.alert("error: " + err);
            } else {
                if (shareDialog) shareDialog.innerHTML = host + response;
            }
        });
    }
);

The CIQ.Share.createImage function is called from the dialog box created by the cq-share-dialog web component:

Share dialog box create image

The CREATE IMAGE button calls the share function of cq-share-dialog; share calls CIQ.Share.createImage.

In the ChartIQ templates, the dialog box is opened from the <cq-share-button> control (which is at the botton left of the chart).

html2canvas

The CIQ.Share.createImage function relies on the third-party html2canvas script included with the library (see js/thirdparty/html2canvas.min.js). The script can be found at https://html2canvas.hertzen.com/.

Instead of taking a screen shot of your chart, html2canvas scans a DOM element, rendering all of the elements down the DOM tree as an image using HTML5 Canvas's toDataURL method. By using html2canvas, the chart engine is able to draw dynamically added elements to the image.

This approach does have some limitations however. The html2canvas script does not render browser plug-ins like Java or Flash.The script does not work on iFrames. The html2canvas script does render most common CSS properties, but may encounter some it does not recognize. Because html2canvas relies on an HTML canvas for rendering, the script has the same CORS limitations of any other canvas element. If you wish to host the script outside of your origin, a proxy is required. Additionally, canvas security features like not allowing a tainted canvas to draw are enforced by default.

drawImage

You can also create your own image rendering function (in place of CIQ.Share.createImage) using the HTML5 canvas's built in drawImage method. By setting the source of an image to your chart container, a canvas can export an image of the chart. By default, the image is a PNG, but other image types can be specified.

You can then upload the image to a server or save it in local storage, for example:

  1. Create a custom function that creates a canvas and image

    CIQ.Share.createAlternateImage = function(stx, cb) {
        let image = document.createElement("img");
        image.src = stx.chart.canvas.toDataURL("image/png");
        let canvas = document.createElement("canvas");
        let context = canvas.getContext("2d");
        if (image && stx.chart.canvas.width && stx.chart.canvas.height) {
        	context.drawImage(image, 0, 0, stx.chart.canvas.width, stx.chart.canvas.height);
        }
        return cb(null, canvas);
    };
    
  2. Create a custom callback function that renders the canvas

    function storeImageLocally(err, canvas) {
        CIQ.localStorage.setItem("manualImg", canvas.toDataURL("image/jpeg"));
    }
    
  3. Call your custom function

    CIQ.Share.createAlternateImage(stxx, storeImageLocally);
    

For more information on how to draw with the HTML canvas, visit MDN or W3Schools.

Next steps

See the examples in the API documentation for: