如何在图形Highcharts中的工具提示中添加值?

时间:2016-03-10 07:54:22

标签: javascript highcharts

有一张图表显示统计数据,生产已在任何城市以任何数量出售。 enter image description here

我需要添加另一个值,它的销售量是多少。在我坐的第二天,我无法弄明白该怎么做。

here is the link

function ev(str) {
        eval(str)
    }


function regression(x, y, typ) {
    var type = (typ == null) ? 'linear' : typ;
    var N = x.length;
    var slope;
    var intercept;
    var SX = 0;
    var SY = 0;
    var SXX = 0;
    var SXY = 0;
    var SYY = 0;
    var Y = [];
    var X = [];

    if (type == 'linear') {
        X = x;
        Y = y;
    } else if (type == 'exp' || type == 'exponential') {
        for (var i = 0; i < y.length; i++) {
            // ignore points <= 0, log undefined.
            if (y[i] <= 0) {
                N = N - 1;
            } else {
                X.push(x[i]);
                Y.push(Math.log(y[i]));
            }
        }
    }

    for (var i = 0; i < N; i++) {
        SX = SX + X[i];
        SY = SY + Y[i];
        SXY = SXY + X[i] * Y[i];
        SXX = SXX + X[i] * X[i];
        SYY = SYY + Y[i] * Y[i];
    }

    slope = (N * SXY - SX * SY) / (N * SXX - SX * SX);
    intercept = (SY - slope * SX) / N;

    return [slope, intercept];
}

function linearRegression(X, Y) {
    var ret;
    ret = regression(X, Y, 'linear');
    return [ret[0], ret[1]];
}

function expRegression(X, Y) {
    var ret;
    var x = X;
    var y = Y;
    ret = regression(x, y, 'exp');
    var base = Math.exp(ret[0]);
    var coeff = Math.exp(ret[1]);
    return [base, coeff];
}

function fitData(data, typ) {
    var type = (typ == null) ? 'linear' : typ;
    var ret;
    var res;
    var x = [];
    var y = [];
    var ypred = [];

    for (i = 0; i < data.length; i++) {
        if (data[i] != null && Object.prototype.toString.call(data[i]) === '[object Array]') {
            if (data[i] != null && data[i][0] != null && data[i][1] != null) {
                x.push(data[i][0]);
                y.push(data[i][1]);
            }
        } else if (data[i] != null && typeof data[i] === 'number') { //If type of X axis is category
            x.push(i);
            y.push(data[i]);
        } else if (data[i] != null && Object.prototype.toString.call(data[i]) === '[object Object]') {
            if (data[i] != null && data[i].x != null && data[i].y != null) {
                x.push(data[i].x);
                y.push(data[i].y);
            }
        }
    }

    if (type == 'linear') {

        ret = linearRegression(x, y);
        for (var i = 0; i < x.length; i++) {
            res = ret[0] * x[i] + ret[1];
            ypred.push([x[i], res]);
        }

        return {
            data: ypred,
            slope: ret[0],
            intercept: ret[1],
            y: function(x) {
                return (this.slope * x) + this.intercept;
            },
            x: function(y) {
                return (y - this.intercept) / this.slope;
            }
        };
    } else if (type == 'exp' || type == 'exponential') {

        ret = expRegression(x, y);
        for (var i = 0; i < x.length; i++) {
            res = ret[1] * Math.pow(ret[0], x[i]);
            ypred.push([x[i], res]);
        }
        ypred.sort();

        return {
            data: ypred,
            base: ret[0],
            coeff: ret[1]
        };
    }
}


function showGraph(zero) {
    zero = typeof zero === "undefined" ? true : zero
    sourceData.sort(function(a, b) {
        return a[0] - b[0]
    })
    series = {}
    seriesSum = []

    dateStart = new Date(sourceData[0][0].toString().replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3"))
    dateEnd = new Date(sourceData[sourceData.length - 1][0].toString().replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3"))
    sourceData.map(function(entry) {
        var date = new Date(entry[0].toString().replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3"))
        var microtime = date.getTime()
        var dealer = entry[2]
        var sum = entry[3]

        //int
        if (typeof entry[1] === "undefined") {
            entry[1] = 0
        }

        //create group
        if (typeof series[dealer] === "undefined") {
            series[dealer] = []
        }

        //find similar day
        if (series[dealer].length > 0 && series[dealer][series[dealer].length - 1][0] === microtime) {
            series[dealer][series[dealer].length - 1][1] += entry[1]
        } else {
            series[dealer].push([microtime, entry[1]])
        }

        //mixed sum
        if (seriesSum.length > 0 && seriesSum[seriesSum.length - 1][0] === microtime) {
            seriesSum[seriesSum.length - 1][1] += entry[1]
        } else {
            seriesSum.push([microtime, entry[1]])
        }
    })

    seriesByName = {}
    seriesArray = []
    _.map(series, function(days, dealer) {
        var newDays = []
        if (zero) {
            for (var dateTemp = new Date(dateStart.getTime()), i = 0; dateTemp < dateEnd; dateTemp.setDate(dateTemp.getDate() + 1)) {
                var microtime = dateTemp.getTime()
                try {
                    if (days[i][0] == microtime) {
                        newDays.push(days[i])
                        i++
                    } else {
                        newDays.push([microtime, 0])
                    }
                } catch (error) {}
            }
        } else {
            newDays = days
        }
        seriesByName[dealer] = newDays
        seriesArray.push({
            name: dealer,
            data: newDays,
            id: dealer,
            dataGrouping: {
                approximation: "sum",
                enabled: true,
                forced: true,
                units: [
                    ['day', [1]]
                ],
                dateTimeLabelFormats: {
                    week: ['За 7 дней начиная от "%A, %b %e, %Y"', '%A, %b %e', '-%A, %b %e, %Y']
                }
            }
        })
    })
    graphContainer = $('#graph').highcharts('StockChart', {
        rangeSelector: {
            buttons: [, {
                type: 'month',
                count: 1,
                text: '1м'
            }, {
                type: 'month',
                count: 2,
                text: '2м'
            }, {
                type: 'month',
                count: 6,
                text: '6м'
            }, {
                type: 'year',
                count: 1,
                text: '1г'
            }, {
                type: 'all',
                text: 'Весь'
            }],
            selected: 5
        },
        tooltip: {
            //pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
            animation: false,
            valueDecimals: 0
        },
        yAxis: [{
            /*labels: {
                formatter: function () {
                    return (this.value > 0 ? ' + ' : '') + this.value + '%';
                }
            },*/
        }, {
            labels: {
                enabled: false
            }
        }],
        plotOptions: {
            series: {
                //compare: 'percent'
            }
        },
        series: seriesArray,
        legend: {
            align: 'center',
            verticalAlign: 'bottom',
            layout: 'horizontal',
            enabled: true
        }
    })

    graph = graphContainer.highcharts()

    grouped = false
    $('#groupWeek').on('click', function() {
        for (var i = 0; i < graph.series.length; i++) {
            var serie = graph.series[i]
            if (grouped) {
                serie.update({
                    dataGrouping: {
                        units: [
                            ['day', [1]]
                        ]
                    }
                })
            } else {
                serie.update({
                    dataGrouping: {
                        units: [
                            ['week', [1]]
                        ]
                    }
                })
            }
        }
        grouped = grouped ? false : true

        if (grouped) {
            $(this).text('Убрать группировку')
        } else {
            $(this).text('Группировать по неделям')
        }
    })

    percent = false
    $('#changePercent').on('click', function() {
        for (var i = 0; i < graph.series.length; i++) {
            var serie = graph.series[i]
            if (percent) {
                serie.update({
                    compare: 'value'
                })
            } else {
                serie.update({
                    compare: 'percent'
                })
            }
        }
        percent = percent ? false : true

        if (percent) {
            $(this).text('Представить в значениях')
        } else {
            $(this).text('Представить в процентах')
        }
    })

    trend = false
    trendArrayId = []
    $('#showTrendline').on('click', function() {
        if (grouped) $('#groupWeek').trigger('click')

        if (trend) {
            while (trendArrayId.length) {
                graph.get(trendArrayId.pop()).remove()
            }
        } else {
            var countSeries = graph.series.length
            for (var iteratorSeries = 0; iteratorSeries < countSeries; iteratorSeries++) {
                var serie = graph.series[iteratorSeries]
                if (serie.name !== 'Navigator') {
                    var data = fitData(seriesByName[serie.name]).data
                    trendArrayId.push('trend_' + serie.name)
                    graph.addSeries({
                        data: data,
                        color: serie.color,
                        visible: serie.visible,
                        linkedTo: serie.name,
                        name: 'Тенденция (' + serie.name + ')',
                        id: 'trend_' + serie.name,
                        dataGrouping: {
                            approximation: "sum",
                            enabled: true,
                            forced: true,
                            units: [
                                ['day', [1]]
                            ]
                        }
                    })
                }
            }
        }
        trend = trend ? false : true

        if (trend) {
            $(this).text('Убрать линии тенденции')
        } else {
            $(this).text('Вывести линии тенденции')
        }
    })


}

var sourceData = [
    [20140829, 63, "Москва и МО", 100],
    [20140930, 1, "Краснодар", 100],
    [20140819, 1, "Краснодар", 100],
    [20141120, 1, "Краснодар", 100],
    [20141010, 1, "Краснодар", 100],
    [20141003, 2, "Краснодар", 100],
    [20140825, 81, "Москва и МО", 100],
    [20140822, 77, "Москва и МО", 100],
    [20140918, 90, "Москва и МО", 100],
    [20140930, 128, "Москва и МО", 100],
    [20141031, 85, "Москва и МО", 100],
    [20140827, 105, "Москва и МО", 100],
    [20141027, 141, "Москва и МО", 100],
];
if (!oldBrowser) {
    $(showGraph(false));
}

1 个答案:

答案 0 :(得分:0)

一个选项是将带有额外值的隐藏系列添加到图表series: { visible: false ... },并仅在工具提示中显示该值。

您可以使用以下属性覆盖工具提示格式化程序:

http://api.highcharts.com/highcharts#tooltip.formatter

确保您拥有tooltip: { shared: true ... }设置,您可以访问给定x值的所有系列值。

这使您可以灵活地使用隐藏的系列或另一个选项将有一个参考字典,您可以使用它来查找额外的值(使用x值作为键)和在工具提示中渲染它。