function set_chart() {

    setTimeout(function() {
        let chartCounter = 0;

        $('.LimitlessLineChart').each(function() {

            chartCounter++;
            let elementChart = $(this);
            elementChart.attr('id', 'LimitlessLineChart' + chartCounter);

            init_line_chart(elementChart[0].id);

        });

    }, 300);
}

// main function
function init_line_chart(chartId) {

    // Define element
    let lineChartElement = document.getElementById(chartId);

    if(lineChartElement) {

        // variables (this will be set by user)
        let titles = ['A'];
        let color = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc', '#a1887f'];
        let animationDuration = 750;
        let seriesNames = ['ONC', 'APR', 'SPR', 'PHX', 'SIG', 'BRG', 'MNT', 'SDK', 'OCT'];
        let xAxisData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
        let yAxisLabelValueFormat = '{value}'; // ex '{value} users'  - https://echarts.apache.org/en/option.html#yAxis.axisLabel.formatter
        let showPointValues = false;
        let boundaryGap = true;
        let inverted = false;
        let showDataZoom = true;
        let stacked = false;
        let markLine = 'average'; // min | max | average
        let series = [];

        seriesNames.forEach(function (val, idx,arr) {

            let chartindex = Math.floor(Math.random() * titles.length);

            series.push(setLineChartSeries(val, [
                Math.floor(Math.random() * 100),
                Math.floor(Math.random() * 100),
                Math.floor(Math.random() * 100),
                Math.floor(Math.random() * 100),
                Math.floor(Math.random() * 100),
                Math.floor(Math.random() * 100),
                Math.floor(Math.random() * 100),
            ], showPointValues, markLine, stacked, chartindex));
        });


        // multichart is true if title param is multiple.
        // legends and datazoom are disabled if multichart.

        let multichart = (titles && titles.length > 1);
        let numberOfCharts = titles ? titles.length : 1;

        // adjust container height before initialising the chart.
        if(multichart) {
            let height = (titles.length * 240); // (chart height = 160 | charts spacing = 80)
            lineChartElement.style.height = height + 'px';
            console.log('adjusted container height', height + 'px');
        }




        let lineChart = echarts.init(lineChartElement);

        // Options
        lineChart.setOption({

            // Chart title
            title: setTitles(titles),

            // Define colors
            color: color,

            // Global text styles
            textStyle: setGlobalTextStyle(),

            // Chart animation duration
            animationDuration: animationDuration,

            // Setup grid
            grid: setGrid(showDataZoom, numberOfCharts),

            // Add legend
            legend: setLegend(seriesNames, multichart),

            // Add tooltip
            tooltip: setTooltip(),

            // Horizontal axis
            xAxis: inverted ? setYAxis(yAxisLabelValueFormat, numberOfCharts) : setXAxis(xAxisData, boundaryGap, numberOfCharts),

            // Vertical axis
            yAxis: inverted ? setXAxis(xAxisData, boundaryGap, numberOfCharts) : setYAxis(yAxisLabelValueFormat, numberOfCharts),

            // Axis pointer
            axisPointer: setAxisPointer(multichart),

            // Zoom control
            dataZoom: setDataZoom(showDataZoom, multichart),

            // Add series
            series: series
        });

        setResizeEvent(lineChartElement, lineChart);
    }
}

// sub functions
function setLineChartSeries(name, data = [], showPointValues  = false, markLineDataType = null, stack = false, index = 0) {

    let series = {
        name: name,
        type: 'line',
        data: data,
        stack: stack,
        smooth: true,
        symbol: 'circle',
        symbolSize: 7,
        label: {
            normal: {
                show: showPointValues
            }
        },
        markLine: {
            data: [{
                type: markLineDataType,
                name: markLineDataType !== null ? (markLineDataType[0].toUpperCase() + markLineDataType.substring(1)) : null,
            }]
        },
        itemStyle: {
            normal: {
                borderWidth: 2
            }
        },
        xAxisIndex: index,
        yAxisIndex: index
    }

    return series;
}

function setXAxis(xAxisData, boundaryGap = true, numberOfCharts = 1) {

    let xAxisArray = [];
    for (let i = 0; i < numberOfCharts; i++) {

        let x = {
            type: 'category',
            boundaryGap: boundaryGap,
            data: xAxisData,
            axisLabel: {
                color: '#fff'
            },
            axisLine: {
                lineStyle: {
                    color: 'rgba(255,255,255,0.25)'
                }
            },
            splitLine: {
                lineStyle: {
                    color: 'rgba(255,255,255,0.1)'
                }
            },
            gridIndex: i
        };

        xAxisArray.push(x);
    }

    return xAxisArray;
}

function setYAxis(yAxisLabelValueFormat,  numberOfCharts = 1) {

    let yAxisArray = [];
    for (let i = 0; i < numberOfCharts; i++) {

        let y = {
            type: 'value',
            axisLabel: {
                formatter: yAxisLabelValueFormat,
                color: '#fff'
            },
            axisLine: {
                lineStyle: {
                    color: 'rgba(255,255,255,0.25)'
                }
            },
            splitLine: {
                lineStyle: {
                    color: 'rgba(255,255,255,0.1)'
                }
            },
            splitArea: {
                show: true,
                areaStyle: {
                    color: ['rgba(255,255,255,0.01)', 'rgba(0,0,0,0.01)']
                }
            },
            gridIndex: i
        };

        yAxisArray.push(y);
    }

    return yAxisArray;
}

function setLegend(legendData, multichart = false) {
    return multichart ? null : {
        data: legendData,
        itemHeight: 8,
        itemGap: 20,
        textStyle: {
            color: '#fff'
        }
    }
}

function setTitles(titles) {

    let arrayTitles = [];
    titles.forEach(function(val, idx, arr) {

        let title = {
            text: val,
        };

        // if single else multichart
        if(idx == 0 && arr.length == 1) {
            title.textStyle = {
                color: '#fff'
            };
        } else {
            title.textStyle = {
                fontSize: 15,
                fontWeight: 500,
                color: '#fff'
            };
            title.left = 'center';
            title.top = 240 * idx; //  (chart height = 160 | charts spacing = 80) * index
        }

        arrayTitles.push(title);
    });

    console.log('titles', arrayTitles);

    return arrayTitles;
}

function setDataZoom(show, multichart = false) {
    return multichart ? null : [
        {
            type: 'inside',
            start: 30,
            end: 70
        },
        {
            show: show,
            type: 'slider',
            start: 30,
            end: 70,
            height: 40,
            bottom: 0,
            borderColor: 'rgba(255,255,255,0.1)',
            fillerColor: 'rgba(0,0,0,0.1)',
            handleStyle: {
                color: '#585f63'
            },
            textStyle: {
                color: '#fff'
            },
            handleStyle: {
                color: '#8893a9'
            },
            dataBackground: {
                areaStyle: {
                    color: 'rgba(0,0,0,0.5)'
                }
            }
        }
    ]
}

function setTooltip() {
    return {
        trigger: 'axis',
        backgroundColor: 'rgba(255,255,255,0.9)',
        padding: [10, 15],
        textStyle: {
            color: '#222',
            fontSize: 13,
            fontFamily: 'Roboto, sans-serif'
        }
    }
}

function setGrid(showDataZoom = false, numberOfCharts = 1) {

    let arrayGrids = [];
    for (let i = 0; i < numberOfCharts; i++) {

        let grid = {
            left: 0,
            containLabel: true
        };

        // if single else multichart
        if(i == 0 && numberOfCharts == 1) {
            grid.right = 40;
            grid.top = 50;
            grid.bottom = showDataZoom ? 60 : 0;
        } else {
            grid.right = 20;
            grid.top = (i == 0) ? 40 : (arrayGrids[i-1].top + 240); // previous top + chart height = 160 + charts spacing = 80
            grid.height = 160;
        }

        arrayGrids.push(grid);
    }

    console.log('grids', arrayGrids);

    return arrayGrids;
}

function setGlobalTextStyle() {
    return {
        fontFamily: 'Roboto, Arial, Verdana, sans-serif',
        fontSize: 13
    };
}

function setAxisPointer(multichart = false) {
    let pointer =  {
        lineStyle: {
            color: 'rgba(255,255,255,0.25)'
        }
    };

    if(multichart) {
        pointer.link = {
            xAxisIndex: 'all'
        };
    }

    return pointer;
}

function setResizeEvent(lineChartElement, lineChart) {
    // Resize function
    let triggerChartResize = function() {
        lineChartElement && lineChart.resize();
    };

    // On sidebar width change
    let sidebarToggle = document.querySelector('.sidebar-control');
    sidebarToggle && sidebarToggle.addEventListener('click', triggerChartResize);

    // On window resize
    let resizeCharts;
    window.addEventListener('resize', function() {
        clearTimeout(resizeCharts);
        resizeCharts = setTimeout(function () {
            triggerChartResize();
        }, 200);
    });
}


$(document).ready(function() {

    if (typeof echarts == 'undefined') {
        console.warn('Warning - echarts.min.js is not loaded.');
        return;
    }

    set_chart();
});