如何使用AngularJS指令和Highcharts在自己的div中设置多个唯一图表

如何使用AngularJS指令和Highcharts在自己的div中设置多个唯一图表,angularjs,highcharts,angularjs-directive,angularjs-ng-repeat,Angularjs,Highcharts,Angularjs Directive,Angularjs Ng Repeat,首先,非常感谢所有能帮助我找到如何让它工作的人 我正在创建一个显示几个主要容器的仪表板。在这些容器里面是一些较小的容器,里面装有高液位计 每个主容器都是使用ng repeat创建的。Ng repeat每次循环时都调用angularjs指令 <span ng-repeat="crs in Locations"><!-- Loops twice in this exammple --> <div ng-receive-stats eventid="eid" lo

首先,非常感谢所有能帮助我找到如何让它工作的人

我正在创建一个显示几个主要容器的仪表板。在这些容器里面是一些较小的容器,里面装有高液位计

每个主容器都是使用ng repeat创建的。Ng repeat每次循环时都调用angularjs指令

<span ng-repeat="crs in Locations"><!-- Loops twice in this exammple -->
    <div ng-receive-stats eventid="eid" locationid="crs.ID"></div>
</span>

该指令使用通用选项创建两个Highchart仪表

app.directive("ngReceiveStats", function () {

// I am the controller for this directive.
function Controller($scope, $element, $attrs, $interval, eventService, $rootScope, $timeout) {
    //SIMULATION FUNCTIONS (TEMPORARY)
    $scope.receiveSiteHealth = 0;
    var p = $interval(function () {
        $scope.receiveSiteHealth = Math.floor((Math.random() * 100) + 1);
    }, 1000);

    $scope.overallHealth = 0;
    var q = $interval(function () {
        $scope.overallHealth = Math.floor((Math.random() * 100) + 1);
    }, 1000);

}

// I bind the $scope to the DOM behaviors.
function link($scope, element, attributes, controllers) {
    //Shared Current/Overall Health Options
    var healthChartOptions = {
        chart: {
            renderTo: 'container',
            type: 'gauge',
            backgroundColor: 'transparent'
        },
        title: {
            text: null
        },
        tooltip: {
            enabled: false
        },
        credits: {
            enabled: false
        },
        exporting: {
            enabled: false
        },
        pane: [{
            startAngle: -90,
            endAngle: 90,
            background: null,
            center: ['50%', '90%'],
            size: 100
        }],
        yAxis: [{
            min: 0,
            max: 100,
            minorTickPosition: 'outside',
            tickPosition: 'outside',
            labels: {
                rotation: 'auto',
                distance: 20
            },
            plotBands: [{
                from: 0,
                to: 50,
                color: '#C02316',
                innerRadius: '110%',
                outerRadius: '105%'
            }, {
                from: 50,
                to: 75,
                color: '#ED9C28',
                innerRadius: '110%',
                outerRadius: '105%'
            }, {
                from: 75,
                to: 100,
                color: '#47A447',
                innerRadius: '110%',
                outerRadius: '105%'
            }],
            pane: 0,
            title: {
                text: '<div class="text-center" style="font-size:22px;margin-bottom:5px;">0</div>',
                useHTML: true,
                y: 0
            }
        }],
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            data: [$scope.currentHealth],
            yAxis: 0
        }]
    };

    //Customize Current Health Options
    var containerA = $('<div style="width:170px; height: 105px;"><img src="/app/content/img/loadingA_32.gif" alt="loading..." /></div>').appendTo('#currentHealth');
    var optsA = healthChartOptions;
    optsA.chart.renderTo = containerA[0];
    var currentHealthChart = new Highcharts.Chart(optsA);

    //Customize Overall Health Options
    var containerB = $('<div style="width:170px; height: 105px;"><img src="/app/content/img/loadingA_32.gif" alt="loading..." /></div>').appendTo('#overallHealth');
    var optsB = healthChartOptions;
    optsB.chart.renderTo = containerB[0];
    var overAllHealthChart = new Highcharts.Chart(optsB);

    //Watch Current Health
    $scope.$watch("receiveSiteHealth", function (newVal, oldVal) {
        if (newVal != oldVal) {
            var chartVal = [parseInt(newVal)];
            currentHealthChart.series[0].setData(chartVal, true);
            currentHealthChart.yAxis[0].setTitle({
                text: '<div class="text-center"><div style="font-size:22px;margin-bottom:10px;">' + newVal + '</div><div style="font-size:11px;">Current Health</div>'
            })
        }
    });

    //Watch Overall Health
    $scope.$watch("overallHealth", function (newVal, oldVal) {
        if (newVal != oldVal) {
            var chartVal = [parseInt(newVal)];
            overAllHealthChart.series[0].setData(chartVal, true);
            overAllHealthChart.yAxis[0].setTitle({
                text: '<div class="text-center"><div style="font-size:22px;margin-bottom:10px;">' + newVal + '</div><div style="font-size:11px;">Overall Health</div>'
            })
        }
    });
}

// Return the directive confirugation.
return ({
    controller: Controller,
    link: link,
    restrict: "EA",
    replace: true,
    templateUrl: '/app/directives/templates/receiveLocationStats.html',
    scope: {
        eventid: '=',
        locationid: '='
    }
});
app.directive(“ngReceiveStats”,函数(){
//我是该指令的控制者。
函数控制器($scope、$element、$attrs、$interval、eventService、$rootScope、$timeout){
//模拟功能(临时)
$scope.receiveSiteHealth=0;
var p=$interval(函数(){
$scope.receiveSiteHealth=Math.floor((Math.random()*100)+1);
}, 1000);
$scope.overallHealth=0;
var q=$interval(函数(){
$scope.overallHealth=Math.floor((Math.random()*100)+1);
}, 1000);
}
//我将$scope绑定到DOM行为。
功能链接($范围、元素、属性、控制器){
//共享当前/总体健康选项
var healthChartOptions={
图表:{
renderTo:'容器',
类型:“仪表”,
背景颜色:“透明”
},
标题:{
文本:空
},
工具提示:{
已启用:false
},
学分:{
已启用:false
},
出口:{
已启用:false
},
窗格:[{
startAngle:-90,
端角:90,
背景:空,
中心:['50%,'90%,],
尺码:100
}],
亚克斯:[{
分:0,,
最高:100,
minorTickPosition:“外部”,
位置:'外部',
标签:{
旋转:“自动”,
距离:20
},
绘图带:[{
起:0,,
致:50,,
颜色:“#C02316”,
内半径:“110%”,
外层:105%
}, {
起:50,,
致:75,
颜色:“#ED9C28”,
内半径:“110%”,
外层:105%
}, {
起:75,
致:100,,
颜色:“#47A447”,
内半径:“110%”,
外层:105%
}],
窗格:0,
标题:{
文本:“0”,
是的,
y:0
}
}],
打印选项:{
仪表:{
数据标签:{
已启用:false
},
拨号:{
半径:“100%”
}
}
},
系列:[{
数据:[$scope.currentHealth],
雅克斯:0
}]
};
//自定义当前运行状况选项
var containerA=$('').appendTo('#currentHealth');
var optsA=健康图表选项;
optsA.chart.renderTo=containerA[0];
var currentHealthChart=新的Highcharts.图表(optsA);
//自定义总体运行状况选项
var containerB=$(“”).appendTo(“#总体健康状况”);
var optsB=健康图表选项;
optsB.chart.renderTo=containerB[0];
var Overall HealthChart=新的Highcharts.图表(optsB);
//关注当前健康状况
$scope.$watch(“接收站点健康”,函数(newVal,oldVal){
如果(newVal!=oldVal){
var chartVal=[parseInt(newVal)];
currentHealthChart.series[0].setData(chartVal,true);
currentHealthChart.yAxis[0]。setTitle({
文本:“”+newVal+“当前运行状况”
})
}
});
//观察整体健康状况
$scope.$watch(“整体健康”,函数(newVal,oldVal){
如果(newVal!=oldVal){
var chartVal=[parseInt(newVal)];
overAllHealthChart.series[0].setData(chartVal,true);
overAllHealthChart.yAxis[0]。setTitle({
文本:“”+newVal+“总体运行状况”
})
}
});
}
//返回指令confiragation。
返回({
控制器:控制器,
链接:链接,
限制:“EA”,
替换:正确,
templateUrl:“/app/directives/templates/receiveLocationStats.html”,
范围:{
eventid:“=”,
位置ID:“=”
}
});
}))

我正在替换指令元素(如上面的ng repeat循环所示):


在templateURL中找到HTML。这将创建主容器

<div class="panel panel-default">
<div class="panel-heading">
    <h3 class="panel-title"><i class="fa fa-bar-chart-o"></i> {{locationid}} - Location Name <a href="" class="pull-right"><i class="fa fa-external-link"></i></a></h3>
</div>
<div class="panel-body">

    <div class="row">
        <div class="col-sm-4">
            <div class="row">
                <div class="col-sm-6" id="currentHealth">

                </div>
                <div class="col-sm-6" id="overallHealth">

                </div>
            </div>
        </div>

        <div class="col-sm-8">
            ...
        </div>
    </div>

</div>

{{locationid}}-位置名称
...

当代码启动时,它确实会拉出Highchart仪表。我遇到的问题是,仪表(在其独特的容器中)都集中在顶部主容器中

<div class="panel panel-default">
<div class="panel-heading">
    <h3 class="panel-title"><i class="fa fa-bar-chart-o"></i> {{locationid}} - Location Name <a href="" class="pull-right"><i class="fa fa-external-link"></i></a></h3>
</div>
<div class="panel-body">

    <div class="row">
        <div class="col-sm-4">
            <div class="row">
                <div class="col-sm-6" id="currentHealth">

                </div>
                <div class="col-sm-6" id="overallHealth">

                </div>
            </div>
        </div>

        <div class="col-sm-8">
            ...
        </div>
    </div>

</div>
我的问题是,如何定义一个唯一的主容器来放置图表。我可以按照HighCharts文档将它们放入自己独特的容器中,但我似乎无法将它们放入自己独特的主(或父)容器中

再次感谢任何能帮我解决这个问题的人

一个想法:

在集装箱声明中:

var containerA = $('<div style="width:170px; height: 105px;"><img src="/app/content/img/loadingA_32.gif" alt="loading..." /></div>').appendTo('#currentHealth');
var containerA=$('').appendTo('currentHealth');

其中appendTo()函数是。每次ng repeat迭代时,都会创建并引用#currentHealth selector。我知道这个ID应该是唯一的,我的直觉告诉我它会解决我的问题。我试过几种方法,但都没用。有什么想法吗?

这可能是因为您使用了与
optsA
optsB
相同的对象
healthChartOptions

当您更改代码时
var optsB = angular.copy(healthChartOptions);
function createChartOptions() {
  var healthChartOptions = { ... };
  return healthChartOptions;
}
var optsA = createChartOptions();
...
var optsB = createChartOptions();
...
<div class="col-sm-6 currentHealth">

</div>
<div class="col-sm-6 overallHealth">

</div>
var outerContainerA = element.find('.currentHealth');
var containerA = $('<div style="width:170px; height: 105px;"><img src="/app/content/img/loadingA_32.gif" alt="loading..." /></div>').appendTo(outerContainerA);

var outerContainerB = element.find('.overallHealth');
var containerB = $('<div style="width:170px; height: 105px;"><img src="/app/content/img/loadingA_32.gif" alt="loading..." /></div>').appendTo(outerContainerB);