Importing and exporting chart layouts

Please note that the web components sample template (chartiq.html) also contains a fully functional storage manager web-component. If you are using web components, see this tutorial instead Importing and exporting chart layouts in chartiq template, as the methods will differ.


The library provides methods for importing and exporting all chart and user settings.

This tutorial discusses how to manage chart settings such as drawings and current layout. Please see Importing and exporting user data to learn about views, color themes, time zone and watch lists.

General concepts

By default, all information is stored in the browser's local storage real time as changes are triggered by the user. And if your implementation does not require this data to be stored in a centralized dataStore, there is nothing else to do to enable this feature.

On the other hand, if you do need the data to be stored elsewhere, you will need to override the exporting and importing routines to link them to your storage facilities.

The exporting (serializing) methods create a serialized object containing the information needed by the chart to restore the settings. You must take these objects and store them in your storage facility (we convert it to a JSON string for easier handling) . When importing the settings back into the chart, you must provide the corresponding importing function the same unchanged object.

Multiple windows or devices

By default the templates will save any change real time to the browser's local storage under a shared key. As such, if multiple windows are open and changes are being made on all of them, the last change will take precedence and override any other changes made on that browser. The loading takes place every time an instrument is loaded to the chart; not real time as changes are made on other windows. So it is possible that a change made on one window is overwritten and never gets seen and by another window. But again all of this can be customized to your liking.

If you have already changed your code to point to a central repository rather than the browser's local storage, the same will happen but it will also affect any other device you use. So the very last change will override any other previous change made on any other device and once a new symbol is loaded, those changes will be reflected.

Triggering and trapping change events

You need to decide when to import the user's data and how often to update it. Depending on your storage facility, you may want to do this real time or just once at the beginning and end of the session.

You can also store the settings both on the local storage, as done by default, and your storage facility.

The library provides a method called STXChart#changeOccurred which can be used to register events that can be trapped by the STXChart#changeCallback function which is used to then take action as needed. This pair of functions allows the library to trigger and react to any event as needed, and can be used for any purpose, not just storage of chart settings.

Example:

function doSomething(){
    // add your code here 
    stxx.changeOccurred("didSomething");
}

// and in your registered  changeCallback function add the pertinent action

stxx.changeCallback=function(stxx, change){
    if(change=="didSomething") takeAction();
}

The default implementation will trigger a real time call to changeCallback every time a layout or drawing change is made. If you wish to change this behavior, simply modify the changeCallback function accordingly to ignore those events.

Chart layout

Importing of the layout is done using STXChart#importLayout

Exporting (serializing) of the layout is done using STXChart#exportLayout

Currently the library automatically triggers events when:

  • layout is changed by adding, deleting or modifying a study or indicator;
  • changing the type of chart (line, bar, candle, etc);
  • a modification is made with any of the drawing tools ( add, delete or modify a drawing or annotation);
  • periodicity is changed;
  • chart range is changed;
  • zoom levels are changed;
  • log scale is changed;

The following code sample covers the main concepts on how to leverage the above methods in a full implementation to store layout changes real time (and in the storage location of your choice), without requiring the user to explicitly click on a 'save' button as he/she interacts with the chart.

// your main HTML code here and other scripts as needed

/** this is the function that loads the chart **/
function displayChart(){
    restoreLayout();        // crate a function to restore the layout and call it now
    runSampleUI();
      stxx.setPeriodicityV2(1, 5);
      STXLoader(true);
      stxx.newChart("SPY", null, null, finishedLoadingNewChart(stxx.chart.symbol, "SPY"));
}

// more code here

/*** define our restore layout function **/
function restoreLayout(){
    // we are importing from local storage, but you can import from any source, by returning the element previously stored for this user by 'importLayout'
    var datum=STX.localStorage.getItem("myChartLayout");
    if(datum==null){
        return;
    }
    stxx.importLayout(JSON.parse(datum));        
}

//more code here

/** define our save layout function **/
function saveLayout(){
    var s=stxx.exportLayout();
    s=JSON.stringify(s);
    STX.localStorageSetItem("myChartLayout", s);    // we are using local storage, but you can save 's' anywhere you want to.
}

//more code here

/*** Register the a function with stxx.changeCallback and it will be called with every change, and you an use to automatically trigger the saving of the layout **/
stxx.changeCallback=function(stxx, change){
    if(change=="layout") saveLayout();
}

That's it...now every time a change is made it will be automatically saved; and upon chart loading, it will be reloaded.

Drawings

The same concepts can be applied to Drawings.

Importing of drawings is done using STXChart#reconstructDrawings

Exporting (serializing) of drawings is done using STXChart#serializeDrawings

Keep in mind that drawings are stored using the symbol as the key, which is different than how the layout is stored. As a result, even tough there will be a single entry in your storage for the layout, there will be a different entry for each set of drawings keyed by the symbol id.

The following is an example on you to define your importing and exporting functions and registering the pertinent events:

function restoreDrawings(){
    // we are importing from local storage, but you can import from any source, by returning the element previously stored for this user by 'serializeDrawings'
    var memory=STX.localStorage.getItem(stxx.chart.symbol);
    if(memory!=null){
        var parsed=JSON.parse(memory);
        if(parsed) stxx.reconstructDrawings(parsed);
        stxx.draw();
    }
}

function saveDrawings(){
    var tmp=stxx.serializeDrawings();
    if(tmp.length==0){
        STX.localStorage.removeItem(stxx.chart.symbol);
    }else{
        STX.localStorageSetItem(stxx.chart.symbol, JSON.stringify(tmp));
    }
}

stxx.changeCallback=function(stxx, change){
    if(change=="layout") saveLayout();
    if(change=="vector") saveDrawings();
}

Local Storage and Safari

Note: when using Safari, the use of local storage may be restricted depending on your particular setup and the browser's settings. Safari does not retain localStorage on a page that is in an iframe from a different domain. If this is how you are setting up the charts, you must ensure your user's browsers are properly configured. To enable local storage functionality, click the "Safari" menu and go to "Preferences". Under the "Privacy" tab select "Always allow" for "Cookies and website data".

Safari Privacy