Source: views/chartView.js

/*global require, define, console, setTimeout */
/*jslint nomen: true, debug: true */

/**
 * @module chartView
 */

define([
    "backbone",
    "framework",
    "highcharts",
    "underscore"
],
    function (Backbone, $, Highcharts, _) {
        "use strict";
        /**
         * @name module:chartView
         * @description Highcharts-extended Backbone.View
         * @class Backbone.View
         * @requires Backbone
         * @requires framework
         * @requires Highcharts
         * @constructor
         * @returns {Function} Backbone.View constructor
         */

        var FONTCOLOR =         "#000",
            BGCOLOR =           "#FFF",
            LEGENDBORDERCOLOR = "#FFF",
            AXISCOLOR =         "#777",
            GRIDLINECOLOR =     "#EEE",
            ENW_WIDGET_CLASS =  ".enw__widget";


        return Backbone.View.extend({
            /**
             * @name module:chartView#type
             * @description Chart type identifier
             * @type {string}
             */
            type: "spline",
            /**
             * @name module:chartView#redraw
             * @description Delayed chart redraw
             * @function
             * @param delay {number} delay in ms
             * @returns {Object} widget view
             */
            redraw: function (delay) {
                /* istanbul ignore else */
                if (this.chart) {
                    var view = this;
                    setTimeout(function () {
                        view.chart.redraw();
                    }, parseInt(delay, 10) || 50);
                }
            },
            initialize: function () {
                this.self = this;
            },
            /**
             * @name module:chartView#getWidget
             * @description Returns widget view link
             * @function
             * @returns {Object} widget view
             */
            getWidget: function () {
                return this.widget;
            },
            /**
             * @name module:chartView#create
             * @description Creates a new highcharts instance
             * @param [node] {String|jQuery|DOM_Element} Node selector or this.$el if undefined
             * @param [type] {String} Chart type or "spline" if undefined
             * @param [options] {Object} Additional options
             * @function
             * @returns {Object} Highcharts instance
             */
            create: function (node, type, options) {
                if (!this.chart) {
                    node = $(node || this.$el);
                    /* istanbul ignore else */
                    if (node) {
                        options = $.extend(
                            true,
                            {
                                getWidget: $.proxy(this.getWidget, this),
                                chart: {

                                    renderTo: node.get(0),
                                    width: node.closest(ENW_WIDGET_CLASS).width()
                                }
                            },
                            this.chartOptions.defaults,
                            this.chartOptions[type || this.type],
                            this.options,
                            options
                        );
                        this.chart = new Highcharts.Chart(options);
                        return this.chart;
                    }
                }
                return null;

            },
            /**
             * @name module:chartView#flush
             * @description Destroys this.chart instance. View instance is still available
             * @function
             * @returns {null} null
             */
            flush: function () {
                this.chart = null;
                return null;
            },
            /**
             * @name module:chartView#render
             * @description Render template and append to DOM.
             * .render() also triggers this.update()
             * @function
             * @returns view {object} current view instance
             */
            render: function (data) {
                this.create();
                this.update.apply(this, arguments);
                return this;
            },
            /**
             * @name module:chartView#update
             * @description Updates chart state by new data
             * @function
             * @returns {boolean} true
             */
            update: function () {
                return true;
            },
            /**
             * @name module:chartView#updateSeries
             * @description Sets data to chart.series specified by index
             * @param data {Array}
             * @param index {Number}
             * @function
             * @returns series {Object|Null} updated series or null
             */
            updateSeries: function (data, index) {
                var k,
                    series = this.chart.series[index || 0];

                if (series) {
                    if (series.data && series.data.length) {
                        for (k = 0; k < data.length; k += 1) {
                            series.data[k].update(data[k], false);
                        }
                    } else {
                        series.update({data: data});
                    }
                    return series;
                }
                return null;
            },
            /**
             * @name module:chartView#updateCol
             * @description Updates column type chart
             * @param arg {*} Data arguments
             * @function
             * @returns series {Object|Null} updated series or null
             */
            updateCol: function () {
                return _.map(arguments, $.proxy(this.updateSeries, this));
            },
            /**
             * @name module:chartView#updatePie
             * @description Updates pie type chart
             * @param arg {*} Data arguments
             * @function
             * @returns series {Object|Null} updated series or null
             */
            updatePie: function () {
                return _.map(arguments, $.proxy(this.updateSeries, this));
            },
            /**
             * @name module:chartView#updateSpline
             * @description Updates spline type chart
             * @param arg {*} Data arguments
             * @function
             * @returns series {Object|Null} updated series or null
             */
            updateSpline: function () {
                var view = this,
                    l = arguments.length,
                    i = l,
                    c = this.chart.series.length;


                if (c > l) {
                    i = c;
                    while (l < i) {


                        this.chart.series[i - 1].remove(false);
                        i -= 1;

                    }
                } else {
                    while (c < i) {
                        i -= 1;
                        this.chart.addSeries({}, false);
                    }
                }

                return _.map(arguments, function (i, j) {
                    var series = view.chart.series[j];
                    series.update(i.data ? i : {data: i}, false);
                    return series;
                });
            },
            /**
             * @name module:chartView#chartOptions
             * @description Chart options extensions
             * @property
             * @type {object}
             */
            chartOptions: {
                defaults: {
                    chart: {
                        backgroundColor: BGCOLOR
                    },
                    credits: { enabled: false },
                    legend: {
                        borderColor: LEGENDBORDERCOLOR,
                        itemStyle: {
                            fontWeight: "normal"
                        }
                    },
                    title: {
                        text: '',
                        style: {
                            color: FONTCOLOR,
                            fontSize: 'normal'
                        }
                    }
                },
                column: {
                    colors: ['#0d233a', '#d4d8e7'], //d4d7e9
                    chart: {
                        type: 'column',
                        height: 300
                    },
                    credits: { enabled: false },
                    legend: { borderColor: '#FFF' },
                    title: {
                        text: "",
                        style: {
                            color: '#000'
                        }
                    },
                    yAxis: {
                        title: {
                            text: 'Показатель, %',
                            style: {
                                color: '#777',
                                fontWeight: 'normal'
                            }
                        },
                        gridLineColor: '#EEE'
                    },
                    xAxis: {
                        title: {
                            text: 'Параллель',
                            style: {
                                color: '#777',
                                fontWeight: 'normal'
                            }
                        }
                    },
                    plotOptions: {
                        column: {
                            pointPadding: 0,
                            borderWidth: 0,
                            animation: true
                        }
                    },
                    tooltip: {
                        enabled: true,
                        formatter: function () {
                            return '<b>' + this.series.chart.options.series[this.series._i].name +
                                ('-' + this.x).toLowerCase() + '</b><br/>' +
                                this.y.toPrecision(3) + '%';
                        }
                    }
                },
                spline: {
                    chart: {
                        type: 'spline'
                    },
                    xAxis: {
                        type: 'linear',
                        categories: []
                    },
                    yAxis: {
                        title: {
                            text: '%',
                            style: {
                                color: AXISCOLOR,
                                fontWeight: 'normal'
                            }
                        },
                        gridLineColor: GRIDLINECOLOR
                    },
                    tooltip: {
                        //enabled: false,
                        formatter: function () {
                            return '<b>' + this.series.name + '</b><br/>' +
                                this.x + ': ' + this.y.toPrecision(3);
                        }
                    },
                    plotOptions: {
                        spline: {
                            dataLabels: {
                                enabled: false
                            },
                            enableMouseTracking: true
                        },
                        series: {
                            cursor: 'pointer',
                            marker: {
                                lineWidth: 1
                            }
                        }
                    }
                },
                pie: {
                    chart: {
                        type: 'pie',
                        height: 280
                    },
                    yAxis: {
                        title: {
                            text: 'Проценты',
                            style: {
                                color: '#777',
                                fontWeight: 'normal'
                            }
                        }
                    },
                    plotOptions: {
                        pie: {
                            shadow: false,
                            center: ['50%', '50%']
                        }
                    },
                    tooltip: {
                        //enabled: false,
                        formatter: function () {
                            return '<b>' + this.point.name + '</b><br/>' +
                                this.y.toPrecision(3) + '%';
                        }
                    }
                }
            }
        });
    });