ajoposor / aoPlotlyAddOn

a Library of functions to be used to add functionality to Plotly
MIT License
0 stars 1 forks source link

aoPlotlyAddOn Library

A javascript library with functions to read data and add features to Plotly's time series plots.

Table of contents

Description

Features

Arguments in detail

divInfo

The divInfo object contains the following properties:

Example

In your html you would structure the wholeDiv and plotDiv and include your plot titles and footnotes in between:

<body>
   <div id="myWholeDiv_01" style="visibility:hidden">

     <!--  Include any header html items to your plot -->
     <h3>My Plot TiTle</h3>

     <div id="myPlotDiv_01" class="plotly" align="left" style="width:100%; height:480px;"></div>

      <!--  Include any footer html items to your plot -->
      (*) Shaded areas indicate recessions.<br>
      Data source: <a href="https://www.quandl.com">Quandl.</a>

  </div>
   <script>
    <!-- JAVASCRIPT CODE GOES HERE -->
   </script>
</body>

In your javascript, declare and defined the divInfo object:

var divInfo = {
    //whole div, including your titles and footnotes. 
    // required to hide div while plot loads.
    wholeDivID: "myWholeDiv_01",

    // div in which plot will be included
    // should be a div within wholeDiv
    plotDivID: "myPlotDiv_01"
};

data

Data follows Plotly's structure and properties. Data is an array of objects, each one with the information for each trace in the plot. The properties x and y, with the dates and value arrays may be supplied directly or be added by the function based on the data sources parameters.

Example

Data example with three traces displayed and one used to make calculations as deflactor. One of the traces has values defined, the others will be fed using the function and the dataSources parameters.

in your javascript:

 var data = [
    {
        type: "scatter",
        name: "S&P 500",
        mode: "lines",
        opacity: 1,
        // the area below this trace will be filled
        // include a transparency percentage so as not to hide the traces there
        fill: "tozeroy",
        fillcolor: "rgba(205, 245,255, 0.20)", //#FAFCFD + 50% transparency
        line: {
            color: "#1A5488",
            width: 3,
            dash: "solid"
        }
    },{
        x: ["2001-01-31", "2017-05-12"];
        y: [ 150, 200];
        type: "scatter",
        name: "my trace",
        mode: "lines",
        opacity: 1,
        line: {
            color: "#1A5488",
            width: 3,
            dash: "solid"
        }
    }, {
        type: "scatter",
        name: "US CPI",
        mode: "lines",
        opacity: 0.8,
        line: {
            color: "#000000",
            width: 1,
            dash: "dash"
        }
    },{
        // this trace will not be displayed but be used as deflactor, 
        // assuming real/nominal options in place
        type: "scatter",
        visible: false,
        name: "US CPI",
        mode: "lines",
        line: {
            color: "#000000",
            width: 1,
            dash: "dash"
        }
    }
];

otherDataProperties

This array of objects links the data array with the dataSources array using a common traceID. The traceID is independent from the trace name property, which is used by Plotly to name the trace.

The otherDataProperties array has the same number of elements as the data array.

It also includes other options for the traces, not part of plotly's traces properties.

Object definition

Each object within the otherDataProperties array has the the following properties:

Example

in your javascript:

 var otherDataProperties = [
    {
        traceID: "S&P 500",
        // this trace will be recalculated if a nominal to real change of base is applied
        toggleRealNominal: true,
    },
    {
        traceID: "US CPI"
        toggleRealNominal: true,
    },{
        // this trace is defined as the deflactor, 
        // it is not changed when a nominal / real change of base is applied to the traces
        traceID: "US CPI deflactor"
        deflactor: true,
        toggleRealNominal: false,           
    }
];

dataSources

This is and array of objects. It has as many elements as sources of data you may have.

Each object in the dataSouces will get a chunk of data, process it and feed as many traces as instructed.

object definition (one object for each element in the dataSources array)

Examples:

Example 1:

var dataSources = [ { // urlType could be "csv", urlType: "csv",

url: "https://rawgit.com/ajoposor/test-csv-files/files/SP500%20sectors-1998-12-2017-04.csv",

// preprocessing options could be added here or in one or more objects of the traces array below
onlyAddXDateSuffix: " 00:00:00-04:00",

traces: [
    {
    xSeriesName: "Date",
    ySeriesName: "SP500 Adjusted Close",
    traceID: "S&P 500"              
    },{
    xSeriesName: "Date_CPI",
    ySeriesName: "CPI_EOM",
    traceID: "US CPI"               
    },              {
    xSeriesName: "Date_CPI",
    ySeriesName: "CPI_EOM",
    traceID: "US CPI deflactor"             
    }
]

}

];


***Example 2**: Test sorting and dates processing options.*
```javascript
var dataSources = [
    {   
    urlType: "arrayOfJsons",

    // all options could be set at dataSources level or at traces level
    // if set at dataSources lelvel they will override traces options.
    // firstItemToRead: "last",
    // processDates: true,
    // optional sort: true / false,
    // optional postProcessDate: "end of month",
    // optional xSeriesName: in case used from postProcessDate or sort
    // xDateSuffix: "",//"T00:00:00-04:00",

    arrayOfJsons: [
    {"Date":"2010-05-24","Date2":"1998-12-31","Open":"135.82","Close":"116.152","Adj Close":"115.173210"},
    {"Date":"2011-03-04","Date2":"2010-05-24","Open":"110.87","Close":"116.017","Adj Close":"130.044304"},
    {"Date":"2011-05-05","Date2":"2012-08-06","Open":"165.94","Close":"116.611","Adj Close":"145.629341"},
    {"Date":"2012-08-06","Date2":"2011-05-05","Open":"155.79","Close":"117.914","Adj Close":"155.918411"},
    {"Date":"2012-10-09","Date2":"2013-03-10","Open":"190.95","Close":"118.988","Adj Close":"175.989319"},
    {"Date":"2013-03-10","Date2":"2012-10-09","Open":"185.77","Close":"119.111","Adj Close":"180.108315"},
    {"Date":"2013-10-11","Date2":"2014-06-12","Open":"300.74","Close":"119.750","Adj Close":"200.742935"},
    {"Date":"2014-06-12","Date2":"2013-10-11","Open":"250.90","Close":"119.250","Adj Close":"250.247139"},
    {"Date":"2015-02-13","Date2":"2015-12-17","Open":"270.10","Close":"119.041","Adj Close":"240.038902"},
    {"Date":"2015-12-17","Date2":"2015-02-13","Open":"290.38","Close":"120.000","Adj Close":"220.990829"},
    {"Date":"2016-01-18","Date2":"2016-04-19","Open":"320.99","Close":"119.988","Adj Close":"240.980911"},
    {"Date":"2016-04-19","Date2":"2016-01-18","Open":"280.39","Close":"119.779","Adj Close":"280.772675"},
    {"Date":"2016-06-20","Date2":"2017-06-11","Open":"340.43","Close":"120.000","Adj Close":"300.990829"},
    {"Date":"2017-01-23","Date2": "","Open": "","Close":"120.08","Adj Close":"280.070"},
    {"Date":"2017-05-24","Date2": "","Open": "","Close":"119.97","Adj Close":"320.960"}
    ],

    traces:[
        {
        // dates follow chronological order, they will be reordered with the firstItemToRead option
        xSeriesName: "Date",
        ySeriesName: "Adj Close",
        traceID: "S&P 500",

        // in case another source of data is used to feed this trace (traceID: "S&P 500")
        // values will be adjusted using a common date
        calculateAdjustedClose: true,

        // dates must follow most recent to oldest order
        firstItemToRead: "last",
        },

        {
        xSeriesName: "Date",
        ySeriesName: "Close",
        traceID: "Some ID",
        calculateAdjustedClose: true,
        firstItemToRead: "last",
        },

        {
        // this dates have no order, they will be sorted from recent to older with the sort option
        // missing dates will not be passed to the data
        xSeriesName: "Date2",
        ySeriesName: "Open",
        traceID: "Second Dates",
        calculateAdjustedClose: true,
        sort: true
        }
    ]
}};

Example 3: Dates are to be changed to end of month.


var dataSources = [
    {
    urlType: "csv",
    url: "https://www.quandl.com/api/v3/datasets/FRED/CPIAUCSL.csv?api_key=yourQuandlApiKey",
    traces:[
        {
        xSeriesName: "Date",
        ySeriesName: "Value",
        postProcessDate: "end of month",
        traceID: "US CPI"
        },

        {
        xSeriesName: "Date",
        ySeriesName: "Value",
        postProcessDate: "end of month",
        traceID: "US CPI deflactor"
        }
        ]
    }
];  

settings

This is an object that controls the features added to your plot.

object structure

timeInfo

Use this object to instruct handling of dates range

object properties

Examples

in your javascript:

var timeInfo = {

    // affects only the initial display, 
    // it will set the initial display to start one year before the current date and end on the current date
    yearsToPlot: 1,

    // include and initial date if applicable (data will be trimmed to before this date)
    tracesInitialDate: "1998-12-31"
};

layout

The layout object follows Plotly's definition.

Example: in your javascript:

// include layout as per Plotly's layout

var layout = {

    yaxis: {
        // the the type of yaxis
        // in case log/linear button option set, 
        // this will be the initial yaxis type display
        type: "log",
        hoverformat: ".4r"
    },

    margin:{
        r: 43
    }
};

options

The options object follows Plotly's definition.

It's and optional parameter.

Example: in your javascript:

// include options as per Plotly's options

var **options** = {

    // this will hide the link to plotly
    showLink: false,

    // this will hid the mode bar
    displayModeBar: false

};

Remarks

Install

Include libraries for plotly, d3.queue, jszip (only if zip files from fred are to be sourced to update recessions (it may be omitted if url set to "") and aoPlotlyAddOn:

<head>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<!-- d3.queue -->
<script src="https://d3js.org/d3-queue.v3.min.js"></script>

<!-- jszip.js -->
<script src="https://rawgit.com/Stuk/jszip/master/dist/jszip.min.js"></script>

<!-- aoPlotlyAddOn.js -->   
<script src="https://raw.githubusercontent.com/ajoposor/aoPlotlyAddOn/master/dist/aoPlotlyAddOn.min.js"></script>
</head>

Use and examples

add library

<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://d3js.org/d3-queue.v3.min.js"></script>
<script src="https://rawgit.com/Stuk/jszip/master/dist/jszip.min.js"></script>
<script src="https://rawgit.com/ajoposor/aoPlotlyAddOn/master/dist/aoPlotlyAddOn.min.js"></script>
</head>

Encapsulate your code

(function() {

    // all the code for one plot here

})();

Putting all together

HTML

<head>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/ajoposor/aoPlotlyAddOn/master/dist/aoPlotlyAddOn.min.js"></script>
</head>
<body>

<div id="myWholeDiv_01" style="visibility:hidden">

<h3>My Plot Title and header</h3>

<div id="myPlotlyDiv_01" class="plotly" align="left" style="width:100%; height:480px;"></div>

Plot footnotes<br>
Data source: <a href="https://www.quandl.com">Quandl.</a>
</div>
<script>
<!-- JAVASCRIPT CODE GOES HERE -->
</script>
</body>

Javascript Code


(function() {

    /* declare and populate variables with parameters

    var divInfo = {
        wholeDivID: "myWholeDiv_01",
        plotDivID: "myPlotlyDiv_01"
    };

    var timeInfo = {
        yearsToPlot: 1,
        tracesInitialDate: "1998-12-31"
    };

    var data = [
        {
            type: "scatter",
            name: "S&P 500",
            mode: "lines",
            opacity: 1,
            fill: "tozeroy",
            fillcolor: "rgba(205, 245,255, 0.20)", //#FAFCFD + 50% transparency
            line: {
                color: "#1A5488",
                width: 3,
                dash: "solid"
            }
        }, ... 
    ];

    var otherDataProperties = [
        {
            traceID: "S&P 500",
            toggleRealNominal: true,
        },...

    ];

    var dataSources = [
    {
    urlType: "csv",
    url: "https://rawgit.com/ajoposor/test-csv-files/master/files/SP500%20sectors-1998-12-2017-04.csv",
    onlyAddXDateSuffix: " 00:00:00-04:00",
    traces: [
        {
        xSeriesName: "Date",
        ySeriesName: "SP500 Adjusted Close",
        traceID: "S&P 500"
        },...
    ]
    }
    ];

    var settings = {
        series: {
            baseFrequency: "daily", 
            baseAggregation: "close", 
            targetFrequencyDisplay: "daily",
        },

        displayRecessions: true,
        allowCompare: true,
        allowDownload: true,
        allowRealNominal: true,
        initialRealNominal: "real",
        baseRealDate: "end of range",
        downloadedFileName: "S&P Sectors Data",
        xAxisNameOnCSV: "Date",
        transformToBaseIndex: true,
        allowFrequencyResampling: true, 
        desiredFrequencies: [
            "daily",
            "weekly",
            "monthly",
            "quarterly",
            "semiannual",
            "annual"
        ],
        allowSelectorOptions: true, // buttons for time range selection, 3m, 6m, 1y, YTD, 5y, etc.
        allowLogLinear: true,
        textAndSpaceToTextRatio: 1.8,
        endOfWeek: 5 // 0 Sunday, 1 Monday, etc.
    };

    var layout = {

        // your layout options

    };

    var options = {

        // your options
    };

    // call function
    aoPlotlyAddOn.newTimeseriesPlot(
                    divInfo, 
                    data, 
                    otherDataProperties, 
                    dataSources,
                    settings, 
                    timeInfo, 
                    layout, 
                    options);

})();

Working Example

test it in codepen

Miscelaneous Functions

Creators

Github
A. Osorio @ajoposor

Release Notes

1.0.0 Function launched

1.1.0

1.1.1

License

Code released under the MIT license.

Docs released under the Creative Commons license.