Javascript 如何提高Highcharts的性能并避免排序数据中的错误15?

Javascript 如何提高Highcharts的性能并避免排序数据中的错误15?,javascript,angularjs,highcharts,highstock,Javascript,Angularjs,Highcharts,Highstock,我正在尝试使用创建高图中的甘特图表示。我从服务器得到一个JSON响应(下面是一个典型的响应结构)。为了创建甘特图表示,我正在两点之间创建一条线。每个点都有一个开始日期和结束日期,为了创建此表示,我在每个点的开始日期和结束日期之间绘制了一条线(我已完成) 来自服务器的响应结构 { "took": 312, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 },

我正在尝试使用创建高图中的甘特图表示。我从服务器得到一个JSON响应(下面是一个典型的响应结构)。为了创建甘特图表示,我正在两点之间创建一条线。每个点都有一个
开始日期
结束日期
,为了创建此表示,我在每个点的
开始日期
结束日期
之间绘制了一条线(我已完成)

来自服务器的响应结构

{
  "took": 312,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4115,
    "max_score": 1,
    "hits": [

    ]
  },
  "aggregations": {
    "top-tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "Process1",
          "doc_count": 6,
          "process": {
            "value": {
              "1449878649000": {
                "start_date": 1449878649000,
                "process_initiator": "lol@surg.com",
                "end_date": 1449878734000,
                "total_seconds": 85
              },
              "1449879753000": {
                "start_date": 1449879753000,
                "process_initiator": "lol@surg.com",
                "end_date": 1449879850000,
                "total_seconds": 97
              },
              "1449881550000": {
                "start_date": 1449881550000,
                "process_initiator": "lol@surg.com",
                "end_date": 1449881631000,
                "total_seconds": 81
              }
            }
          }
        },
        {
          "key": "Process2",
          "doc_count": 1,
          "process": {
            "value": {
              "1449971262000": {
                "start_date": 1449971262000,
                "process_initiator": "lol@surg.com",
                "end_date": 1449971266000,
                "total_seconds": 4
              }
            }
          }
        }
      ]
    }
  }
}
代码也

var-app=angular.module('app',[]);
应用指令('operationalhighstackstock',函数(){
返回{
限制:'E',
范围:正确,
链接:函数postLink(范围、元素、属性){
范围$watch('operationHighChartsData',函数(值){
新的高点图表。股票图表(价值);
});
}
};
});
//2014-11-30T18:15:25.000-08:00
app.controller('MainCtrl',['$scope',函数($scope){
$scope.excludeValue={
数据:0
};
$scope.isExcludeneed=true;
var opExcludeMinutes=1,
代理名称=“代理名称”,
颜色代码=[“8CC051”、“967BDC”、“5D9CEC”、“FB6E52”、“EC87BF”、“46CEAD”、“FFCE55”、“193441”、“193441”、“BEEB9F”、“E3DB9A”、“917A56”];
var设置汇总显示=功能(e){
如果(e.min==null | | e.max==null)
$scope.hideRangeSlider=true;
其他的
$scope.hideRangeSlider=false;
$scope.minimumSelectedValue=e.min;
$scope.maximumSelectedValue=e.max;
}
var getHichartsData=函数(结果){
var tasksar=[],
seriesar=[],
userArr=[],
processArr=[];
var agentSeries=[],
agentData={},
processSeries=[],
taskData={},
idx=0,
opProcessBucket=esResponse.aggregations[“top tags”].Bucket,
seriesData={};
var opBucketLength=opProcessBucket.length;
对于(var opProcessBucketIndex=0;opProcessBucketIndex$scope.excludeValue.data&&$scope.isExcludened){
if(intervalIndex==0 | |进程|名称==null){
进程名称=opProcessBucket[opProcessBucketIndex][“key”];
processArr.push(opProcessBucket[opProcessBucketIndex][“键]);
}
userArr.push(intervalBucket[key].process\u启动器);
processIntervalObj[“任务_id”]=opProcessBucket[opProcessBucketIndex][“键”];
processIntervalObj[“from”]=st;
var lFromtime=moment.utc(st.toDate();
lFromtime=力矩(lFromtime).format('MM/DD/YY HH:MM');
var lTotime=矩.utc(et).toDate();
lTotime=力矩(lTotime).格式('MM/DD/YY HH:MM');
processIntervalObj[“到”]=et;
processIntervalObj[“颜色”]=“#FFCC4E”;
processIntervalObj[“fromDateString”]=lFromtime;
processIntervalObj[“toDateString”]=lTotime;
processIntervalObj[“进程\启动器”]=intervalBucket[key]。进程\启动器==null?“未知”:intervalBucket[key]。进程\启动器;
processIntervalObj[“总秒数”]=intervalBucket[key]。总秒数;
//sortElementArr.push(价格间[“排序”][0]);
tasksIntervalArr.push(processIntervalObj);
}
}
opTaskidObj[“name”]=进程名称;
OptaskIDiterValobj[“名称”]=进程名称;
opTaskidObj[“数据”]=[];
opTaskidIntervalObj[“间隔”]=tasksIntervalArr;
opTaskidIntervalObj[“间隔”]=tasksIntervalArr;
idx++;
如果(tasksIntervalArr.length>0){
processSeries.push(opTaskidIntervalObj);
agentSeries.push(opTaskidObj);
}
//}
}
seriesData[“title”]=“Test”//项[“key”];
var系列=[];
(processSeries.reverse()).forEach(函数(任务,i){
变量
var app = angular.module('app', []);

app.directive('operationalhighstackstock', function() {
    return {
        restrict: 'E',
        scope: true,
        link: function postLink(scope, element, attrs) {
            scope.$watch('operationHighChartsData', function(values) {
                new Highcharts.StockChart(values);
            });
        }
    };
});
//2014-11-30T18:15:25.000-08:00
app.controller('MainCtrl', ['$scope', function($scope) {
    $scope.excludeValue = {
        data: 0
    };
    $scope.isExcludeNeeded = true;
    var opExcludeMinutes = 1,
        AGENT_NAMES = "agent_names",
        colorCodes = ["#8CC051", "#967BDC", "#5D9CEC", "#FB6E52", "#EC87BF", "#46CEAD", "#FFCE55", "#193441", "#193441", "#BEEB9F", "#E3DB9A", "#917A56"];

    var setSummaryDisplay = function(e) {
        if (e.min === null || e.max === null)
            $scope.hideRangeSlider = true;
        else
            $scope.hideRangeSlider = false;
        $scope.minimumSelectedValue = e.min;
        $scope.maximumSelectedValue = e.max;
    }

    var getHichartsData = function(result) {
        var tasksArr = [],
            seriesArr = [],
            userArr = [],
            processArr = [];

        var agentSeries = [],
            agentData = {},
            processSeries = [],
            taskData = {},
            idx = 0,
            opProcessBucket = esResponse.aggregations["top-tags"].buckets,
            seriesData = {};
        var opBucketLength = opProcessBucket.length;
        for (var opProcessBucketIndex = 0; opProcessBucketIndex < opBucketLength; ++opProcessBucketIndex) {
            //opProcessBucket.forEach(function(processEntry) {
            //if (opProcessBucket[opProcessBucketIndex]["key"] == $scope.gpDropDownTitle) {
            var intervalBucket = opProcessBucket[opProcessBucketIndex]["process"]["value"], //opProcessBucket[opProcessBucketIndex]["top_tag_hits"]["hits"]["hits"],
                intervalArr = [],
                tasksIntervalArr = [],
                opTaskidObj = {},
                opTaskidIntervalObj = {},
                process_name = null,
                sortElementArr = [];
            for (var key in intervalBucket) {
                //intervalBucket.forEach(function(intervalEntry, intervalIndex) {
                var intervalObj = {},
                    intervalObj2ndpoint = {},
                    processIntervalObj = {},
                    tintervalArr = [],
                    intervalIndex = 0,
                    start_temp = parseInt(key),
                    end_temp = intervalBucket[key].end_date; //start_temp = intervalBucket[key].start_date, end_temp = intervalBucket[key].end_date;
                //added here since response contains null value and data load will take almost 1 date, verified with Bhavesh
                $scope.currentDateTime = new Date().getTime();
                if (end_temp == null)
                    end_temp = $scope.currentDateTime;
                var st = new Date(moment(start_temp).valueOf()).getTime();
                var et = new Date(moment(end_temp).valueOf()).getTime();
                var duration = moment.duration(moment(et).diff(moment(st)));
                var minutes = duration.asMinutes();
                if (minutes > $scope.excludeValue.data && $scope.isExcludeNeeded) {
                    if (intervalIndex == 0 || process_name == null) {
                        process_name = opProcessBucket[opProcessBucketIndex]["key"];
                        processArr.push(opProcessBucket[opProcessBucketIndex]["key"]);
                    }
                    userArr.push(intervalBucket[key].process_initiator);
                    processIntervalObj["task_id"] = opProcessBucket[opProcessBucketIndex]["key"];
                    processIntervalObj["from"] = st;
                    var lFromtime = moment.utc(st).toDate();
                    lFromtime = moment(lFromtime).format('MM/DD/YY HH:mm');
                    var lTotime = moment.utc(et).toDate();
                    lTotime = moment(lTotime).format('MM/DD/YY HH:mm');
                    processIntervalObj["to"] = et;
                    processIntervalObj["color"] = "#FFCC4E";
                    processIntervalObj["fromDateString"] = lFromtime;
                    processIntervalObj["toDateString"] = lTotime;
                    processIntervalObj["process_initiator"] = intervalBucket[key].process_initiator == null ? 'Unknown' : intervalBucket[key].process_initiator;
                    processIntervalObj["total_seconds"] = intervalBucket[key].total_seconds;
                    //sortElementArr.push(intervalEntry["sort"][0]);
                    tasksIntervalArr.push(processIntervalObj);
                }
            }
            opTaskidObj["name"] = process_name;
            opTaskidIntervalObj["name"] = process_name;
            opTaskidObj["data"] = [];
            opTaskidIntervalObj["intervals"] = tasksIntervalArr;
            opTaskidIntervalObj["intervals"] = tasksIntervalArr;
            idx++;
            if (tasksIntervalArr.length > 0) {
                processSeries.push(opTaskidIntervalObj);
                agentSeries.push(opTaskidObj);
            }
            //}
        }

        seriesData["title"] = "Test"; //item["key"];

        var series = [];
        (processSeries.reverse()).forEach(function(task, i) {
            var item = {
                name: task.name,
                data: [],
                turboThreshold: 1100000
            };
            (task.intervals).forEach(function(interval, j) {
                item.data.push({
                    task_id: interval.task_id,
                    x: interval.from,
                    y: i,
                    from: interval.from,
                    to: interval.to,
                    color: interval.color,
                    fromDateString: interval.fromDateString,
                    toDateString: interval.toDateString,
                    total_seconds: interval.total_seconds,
                    process_initiator: interval.process_initiator
                }, {
                    task_id: interval.task_id,
                    x: interval.to,
                    y: i,
                    from: interval.from,
                    to: interval.to,
                    color: interval.color,
                    fromDateString: interval.fromDateString,
                    toDateString: interval.toDateString,
                    total_seconds: interval.total_seconds,
                    process_initiator: interval.process_initiator
                });
                // add a null value between intervals
                if (task.intervals[j + 1]) {
                    item.data.push([(interval.to + task.intervals[j + 1].from) / 2, null]);
                }
            });
            series.push(item);
        })
        seriesData["data"] = series;
        seriesData["tasks"] = processSeries;
        seriesArr.push(seriesData);
        return seriesArr;
    }

    $scope.agentSeriesData = getHichartsData(esResponse);

    var tasks = $scope.agentSeriesData[0].tasks;
    var seriesData = $scope.agentSeriesData[0].data;
    var xAxisStepping = 1 * 3600 * 1000;
    var chart = new Highcharts.StockChart({
        chart: {
            renderTo: 'container',
            height: 600,
            events: {
                load: function(e) {
                    var max = this.xAxis[0].max;
                    var range = (24 * 3600 * 1000) * 7; // one day * 7
                    if ($scope.isInit || $scope.filterReseted) {
                        $scope.filterReseted = false;
                        this.xAxis[0].setExtremes(max - range, max);
                    }
                    setSummaryDisplay.call(this.xAxis[0], {
                        trigger: "navigator",
                        min: this.xAxis[0].min,
                        max: this.xAxis[0].max
                    });
                }
            }
        },
        title: {},
        credits: {
            enabled: false
        },
        xAxis: {
            type: 'datetime',
            gridLineWidth: 1,
            tickInterval: xAxisStepping,
            //ordinal:false,
            dateTimeLabelFormats: {
                month: '%b %e, %Y'
            },
            events: {
                afterSetExtremes: setSummaryDisplay
            },
            minRange: 1000
        },
        yAxis: {
            tickInterval: 1,
            gridLineWidth: 1,
            labels: {
                enabled: false,
                formatter: function() {
                    if (tasks[this.value]) {
                        return tasks[this.value].name;
                    }
                }
            },
            startOnTick: false,
            endOnTick: false,
            title: {
                text: 'Process'
            }
        },
        animation: false,
        rangeSelector: {
            enabled: false
        },
        navigator: {
            enabled: true
        },
        legend: {
            enabled: false
        },
        tooltip: {
            shared: false,
            formatter: function() {
                var str = '';
                str += 'Process: ' + this.series.name + '<br>';
                str += 'From: ' + Highcharts.dateFormat('%m/%d/%y %H:%M:%S', this.point.from) + '<br>';
                str += 'To: ' + Highcharts.dateFormat('%m/%d/%y %H:%M:%S', this.point.to) + '<br>';
                return str;
            }
        },
        plotOptions: {
            line: {
                lineWidth: 10,
                marker: {
                    enabled: false
                },
                dataLabels: {
                    enabled: false,
                    borderRadius: 5,
                    borderWidth: 1,
                    y: -6,
                    formatter: function() {
                        return this.series.name;
                    }
                },
                states: {
                    hover: {
                        lineWidth: 10
                    }
                }
            },
            series: {
                cursor: 'pointer',
                animation: false,
                point: {
                    events: {
                        click: function() {
                            $scope.selectedGuide = this.series.name;
                            //$scope.showTableView();
                        }
                    }
                },
                turboThreshold: 100000000,
                dataGrouping: {
                    enabled: false
                }
            }
        },
        scrollbar: {
            enabled: false
        },
        series: seriesData
    });

    $scope.operationHighChartsData = chart;

}]);
for (var i in seriesData) {
  seriesData[i].data.sort(function(a, b) {
    if (a.x > b.x) {
      return 1;
    }

    if (b.x > a.x) {
      return -1;
    }

    return 0;
  });
}
if (task.intervals[j + 1]) {
    item.data.push([(interval.to + task.intervals[j + 1].from) / 2, null]);
}
// add a null value between intervals
if (task.intervals[j + 1]) {
    item.data.push({
        task_id: interval.task_id,
        x: (interval.to + task.intervals[j + 1].from) / 2,
        y: null,
        from: (interval.to + task.intervals[j + 1].from) / 2,
        to: (interval.to + task.intervals[j + 1].from) / 2
    });
}