Cards and tag values are showing up on the card overview screen, but the tag data doesn't seem correct
This commit is contained in:
@@ -18,6 +18,90 @@ var pad = function(str, max) {
|
||||
}
|
||||
};
|
||||
|
||||
var getCardGraphOptions = function(surface, downhole){
|
||||
var limits = {
|
||||
sMaxPos: surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.max(y,z);})+ 20,
|
||||
sMinPos: surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.min(y,z);})- 20,
|
||||
sMaxLoad: surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
sMinLoad: surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
dMaxLoad: downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
dMinLoad: downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
};
|
||||
|
||||
var surfaceOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.sMinLoad,
|
||||
max: limits.sMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'surface',
|
||||
color: 'steelblue',
|
||||
type: ['line', 'area'],
|
||||
striped: true,
|
||||
label: 'Surface Card',
|
||||
id: "surfaceCard"
|
||||
}
|
||||
],
|
||||
grid: {
|
||||
x: true,
|
||||
y: true
|
||||
}
|
||||
};
|
||||
var downholeOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.dMinLoad,
|
||||
max: limits.dMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'downhole',
|
||||
color: 'steelblue',
|
||||
type: ['line', 'area'],
|
||||
label: 'Downhole Card',
|
||||
id: "downholeCard",
|
||||
}
|
||||
],
|
||||
grid: {
|
||||
x: true,
|
||||
y: true
|
||||
}
|
||||
};
|
||||
return({surf: surfaceOptions, down: downholeOptions});
|
||||
};
|
||||
|
||||
wellCtrls.factory('Page', function($log) {
|
||||
var title = 'default';
|
||||
var page = 'default';
|
||||
@@ -627,23 +711,12 @@ wellCtrls.controller('fileListTodayCtrl', function($scope, $http, $routeParams,
|
||||
wellCtrls.controller('dashboardCtrl', function($scope, $route, $http, $routeParams, json, Page, Alerts, $log) {
|
||||
Page.setTitle('Dashboard');
|
||||
Page.setPage('dashboard');
|
||||
// $scope.currentPage = 1;
|
||||
// $scope.numPerPage = 10;
|
||||
// $scope.maxSize = 9;
|
||||
$scope.dateListLoading = true;
|
||||
var getDateList = json.getDateList();
|
||||
getDateList.then(function(data) {
|
||||
$scope.dateListLoading = false;
|
||||
$scope.dates = data.dates;
|
||||
$scope.currentDate = $scope.dates[0];
|
||||
// $scope.numPages = function() {
|
||||
// return Math.ceil($scope.dates.length / $scope.numPerPage);
|
||||
// };
|
||||
// $scope.$watch('currentPage + numPerPage', function() {
|
||||
// var begin = ($scope.currentPage - 1) * $scope.numPerPage;
|
||||
// var end = begin + $scope.numPerPage;
|
||||
// $scope.filteredDates = $scope.dates.slice(begin, end);
|
||||
// });
|
||||
});
|
||||
$scope.dashboard = function() {
|
||||
var getCurrentTagValues = json.getCurrentTagValues();
|
||||
@@ -684,106 +757,13 @@ wellCtrls.controller('dashboardCtrl', function($scope, $route, $http, $routePara
|
||||
});
|
||||
$scope.downhole.push($scope.downhole[0]);
|
||||
|
||||
var limits = {
|
||||
sMaxPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.max(y,z);})+ 20,
|
||||
sMinPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.min(y,z);})- 20,
|
||||
sMaxLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
sMinLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
dMaxLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
dMinLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
};
|
||||
$scope.limits = limits;
|
||||
$scope.card_graph_data = {
|
||||
surface: $scope.surface,
|
||||
downhole: $scope.downhole
|
||||
};
|
||||
|
||||
$scope.surfaceOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.sMinLoad,
|
||||
max: limits.sMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'surface',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Surface Card',
|
||||
id: "surfaceCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
},
|
||||
drawLegend: true,
|
||||
drawDots: true,
|
||||
columnsHGap: 5
|
||||
};
|
||||
$scope.downholeOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.dMinLoad,
|
||||
max: limits.dMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'downhole',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Downhole Card',
|
||||
id: "downholeCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
},
|
||||
drawLegend: true,
|
||||
drawDots: true,
|
||||
columnsHGap: 5
|
||||
};
|
||||
var graphOptions = getCardGraphOptions($scope.surface, $scope.downhole);
|
||||
$scope.surfaceOptions = graphOptions.surf;
|
||||
$scope.downholeOptions = graphOptions.down;
|
||||
});
|
||||
|
||||
var getTotals = json.getTotals();
|
||||
@@ -792,9 +772,6 @@ wellCtrls.controller('dashboardCtrl', function($scope, $route, $http, $routePara
|
||||
});
|
||||
};
|
||||
$scope.dashboard();
|
||||
// socket.on('notification', function(data) {
|
||||
// $scope.dashboard();
|
||||
// });
|
||||
});
|
||||
|
||||
wellCtrls.controller('totalsCtrl', function($scope, json, Page, $log){
|
||||
@@ -830,7 +807,7 @@ wellCtrls.controller('totalsCtrl', function($scope, json, Page, $log){
|
||||
$scope.refresh();
|
||||
});
|
||||
|
||||
wellCtrls.controller('cardDataCtrl', function($scope, $http, $routeParams, json, Page) {
|
||||
wellCtrls.controller('cardDataCtrl', function($scope, $http, $routeParams, json, Page, $log) {
|
||||
$scope.loading = true;
|
||||
Page.setTitle('Card Data');
|
||||
Page.setPage('cardData');
|
||||
@@ -840,119 +817,43 @@ wellCtrls.controller('cardDataCtrl', function($scope, $http, $routeParams, json,
|
||||
$scope.dates = data.dates;
|
||||
$scope.currentDate = $scope.dates[0];
|
||||
});
|
||||
$http.get('/json/card/' + $routeParams.id).success(function(cData) {
|
||||
if (cData.error){
|
||||
$scope.error = cData.error;
|
||||
$scope.loading = false;
|
||||
} else {
|
||||
$scope.cardData = cData.card_data;
|
||||
//$scope.cardData.dateTime = new Date($scope.cardData.localtime.replace(" ","T"));
|
||||
|
||||
$scope.surface = cData.card_data.Surface_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Surface_Position[i], load:cData.card_data.Surface_Load[i]};
|
||||
});
|
||||
$scope.surface.push($scope.surface[0]);
|
||||
$scope.downhole = cData.card_data.Downhole_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Downhole_Position[i], load:cData.card_data.Downhole_Load[i]};
|
||||
});
|
||||
$scope.downhole.push($scope.downhole[0]);
|
||||
var limits = {
|
||||
sMaxPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.max(y,z);})+ 20,
|
||||
sMinPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.min(y,z);})- 20,
|
||||
sMaxLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
sMinLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
dMaxLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
dMinLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
};
|
||||
$scope.limits = limits;
|
||||
$scope.card_graph_data = {
|
||||
surface: $scope.surface,
|
||||
downhole: $scope.downhole
|
||||
};
|
||||
var getCard = json.getCard($routeParams.id);
|
||||
getCard.then(function(cData){
|
||||
cData = cData.data;
|
||||
$scope.cardData = cData.card_data;
|
||||
$scope.cardData.Stroke_Time = new Date($scope.cardData.Stroke_Time);
|
||||
//$scope.cardData.dateTime = new Date($scope.cardData.localtime.replace(" ","T"));
|
||||
|
||||
$scope.surfaceOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.sMinLoad,
|
||||
max: limits.sMaxLoad
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'surface',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Surface Card',
|
||||
id: "surfaceCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
$scope.surface = cData.card_data.Surface_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Surface_Position[i], load:cData.card_data.Surface_Load[i]};
|
||||
});
|
||||
$scope.surface.push($scope.surface[0]);
|
||||
|
||||
$scope.downhole = cData.card_data.Downhole_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Downhole_Position[i], load:cData.card_data.Downhole_Load[i]};
|
||||
});
|
||||
$scope.downhole.push($scope.downhole[0]);
|
||||
|
||||
$scope.card_graph_data = {
|
||||
surface: $scope.surface,
|
||||
downhole: $scope.downhole
|
||||
};
|
||||
var graphOptions = getCardGraphOptions($scope.surface, $scope.downhole);
|
||||
$scope.surfaceOptions = graphOptions.surf;
|
||||
$scope.downholeOptions = graphOptions.down;
|
||||
|
||||
var getTagsAtTime = json.getTagsAtTime($scope.cardData.Stroke_Time.getTime() / 1000);
|
||||
getTagsAtTime.then(function(d){
|
||||
var data = d.data;
|
||||
if (data.status == "OK"){
|
||||
$scope.loading = false;
|
||||
$scope.tagData = {};
|
||||
for(var i=0; i < data.vals.length; i++){
|
||||
$scope.tagData[data.vals[i].name] = data.vals[i];
|
||||
}
|
||||
};
|
||||
$scope.downholeOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.dMinLoad,
|
||||
max: limits.dMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'downhole',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Downhole Card',
|
||||
id: "downholeCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
},
|
||||
drawLegend: true,
|
||||
drawDots: true,
|
||||
columnsHGap: 5
|
||||
};
|
||||
$scope.loading = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -29,25 +29,25 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div id="Status" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Status:</h4><h5>{{cardData.Card_Type}}</h5></div>
|
||||
<div id="Status" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Status:</h4><h5>{{cardData.Card_Type}}</h5><h6>at {{tagData.fillage_percent.dtime * 1000 | date: "medium"}}</h6></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="FillageGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Pump Fillage:</h4><h5>{{cardData.Fillage_Percent | number:3}} %</h5></div>
|
||||
<div id="FillageGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Pump Fillage:</h4><h5>{{tagData.fillage_percent.val | number:3}} %</h5><h6>at {{tagData.fillage_percent.dtime * 1000 | date: "medium"}}</h6></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="FAPGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Fluid Above Pump:</h4><h5>{{cardData.Fluid_Level | number:3}} ft.</h5></div>
|
||||
<div id="FAPGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Fluid Above Pump:</h4><h5>{{tagData.fluid_level.val | number:3}} ft.</h5><h6>at {{tagData.fluid_level.dtime * 1000 | date: "medium"}}</h6></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="PRHPGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Polished Rod HP:</h4><h5>{{cardData.Polished_Rod_HP | number:3}} HP</h5></div>
|
||||
<div id="PRHPGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Polished Rod HP:</h4><h5>{{tagData.polished_rod_hp.val | number:3}} HP</h5></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="PMPHPGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Pump HP:</h4><h5>{{cardData.Pump_HP | number:3}} HP</h5></div>
|
||||
<div id="PMPHPGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Pump HP:</h4><h5>{{tagData.pump_hp.val | number:3}} HP</h5></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="SpeedGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Speed:</h4><h5>{{cardData.SPM | number:3}} SPM</h5></div>
|
||||
<div id="SpeedGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Speed:</h4><h5>{{tagData.spm.val | number:3}} SPM</h5></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="FluidLoadGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Fluid Load:</h4><h5>{{cardData.Downhole_Fluid_Load | number:3}} lbs.</h5></div>
|
||||
<div id="FluidLoadGauge" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Fluid Load:</h4><h5>{{tagData.downhole_fluid_load.val | number:3}} lbs.</h5></div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div id="LastUpdated" class="gauge well" style="width:95%; text-align:center; margin:10px;"><h4>Current Stroke:</h4><h5>{{cardData.Stroke_Time | date: "medium"}}</h5></div>
|
||||
@@ -60,26 +60,26 @@
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="progress" style="margin:10px;">
|
||||
<div class="progress-bar progress-bar-striped active" id="surface_stroke_length" role="progressbar" aria-valuenow="{{ cardData.Surface_Stroke_Length }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ cardData.Surface_Stroke_Length }}%;">
|
||||
Surface Stroke Length: {{ cardData.Surface_Stroke_Length | number:3 }} in.
|
||||
<div class="progress-bar progress-bar-striped active" id="surface_stroke_length" role="progressbar" aria-valuenow="{{ tagData.surface_stroke_length.val }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ tagData.surface_stroke_length.val }}%;">
|
||||
Surface Stroke Length: {{ tagData.surface_stroke_length.val | number:3 }} in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress" style="margin:10px;">
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_gross_stroke" role="progressbar" aria-valuenow="{{ cardData.Downhole_Gross_Stroke }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ cardData.Downhole_Gross_Stroke }}%;">
|
||||
Downhole Gross Stroke: {{ cardData.Downhole_Gross_Stroke | number:3 }} in.
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_gross_stroke" role="progressbar" aria-valuenow="{{ tagData.downhole_gross_stroke.val }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ tagData.downhole_gross_stroke.val }}%;">
|
||||
Downhole Gross Stroke: {{ tagData.downhole_gross_stroke.val | number:3 }} in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress" style="margin:10px;">
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_adjusted_gross_stroke" role="progressbar" aria-valuenow="{{ cardData.Downhole_Adjusted_Gross_Stroke }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ cardData.Downhole_Adjusted_Gross_Stroke }}%;">
|
||||
Downhole Adjusted Gross Stroke: {{ cardData.Downhole_Adjusted_Gross_Stroke | number:3 }} in.
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_adjusted_gross_stroke" role="progressbar" aria-valuenow="{{ tagData.downhole_adjusted_gross_stroke.val }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ tagData.downhole_adjusted_gross_stroke.val }}%;">
|
||||
Downhole Adjusted Gross Stroke: {{ tagData.downhole_adjusted_gross_stroke.val | number:3 }} in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress" style="margin:10px;">
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_net_stroke" role="progressbar" aria-valuenow="{{ cardData.Downhole_Net_Stroke }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ cardData.Downhole_Net_Stroke }}%;">
|
||||
Downhole Net Stroke: {{ cardData.Downhole_Net_Stroke | number:3 }} in.
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_net_stroke" role="progressbar" aria-valuenow="{{ tagData.downhole_net_stroke.val }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ tagData.downhole_net_stroke.val }}%;">
|
||||
Downhole Net Stroke: {{ tagData.downhole_net_stroke.val | number:3 }} in.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<pre>{{tagValues}}</pre>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="active"><a href="/">Last Stroke</a></li>
|
||||
<li><a href="/#/totals">Today's Totals</a></li>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
wellCtrls = angular.module 'wellCtrls', ['n3-line-chart', 'ui.bootstrap', 'ngAnimate', 'ngJustGage']
|
||||
|
||||
dateConversion = (raw) ->
|
||||
converted = raw.slice(4, 6) + '/' + raw.slice(6, 8) + '/' + raw.slice(0, 4);
|
||||
converted = raw.slice(4, 6) + '/' + raw.slice(6, 8) + '/' + raw.slice(0, 4)
|
||||
x =
|
||||
conv: converted,
|
||||
unconv: raw
|
||||
@@ -11,35 +10,155 @@ dateConversion = (raw) ->
|
||||
pad = (str, max) ->
|
||||
str = str.toString()
|
||||
if str.length < max
|
||||
x = pad '0' + str, max
|
||||
ret = pad('0' + str, max);
|
||||
else
|
||||
x = str
|
||||
x
|
||||
ret = str;
|
||||
ret
|
||||
|
||||
wellCtrls.factory 'Page', ($log) ->
|
||||
title = 'default'
|
||||
page = 'default'
|
||||
ret =
|
||||
title: () ->
|
||||
title
|
||||
setTitle: (newTitle) ->
|
||||
title = newTitle
|
||||
page: () ->
|
||||
page
|
||||
setPage: (newPage) ->
|
||||
page = newPage
|
||||
maxPos = (card) ->
|
||||
card.map (x) ->
|
||||
x.position
|
||||
.reduce (y,z)->
|
||||
Math.max y,z
|
||||
|
||||
wellCtrls.factory 'Alerts', ($log) ->
|
||||
alerts = []
|
||||
ret =
|
||||
add: (alt) ->
|
||||
alerts.push alt
|
||||
remove: (indx) ->
|
||||
alerts.splice indx, 1
|
||||
clear: () ->
|
||||
alerts = []
|
||||
get: () ->
|
||||
alerts;
|
||||
minPos = (card) ->
|
||||
card.map (x) ->
|
||||
x.position
|
||||
.reduce (y,z)->
|
||||
Math.min y,z
|
||||
|
||||
maxLoad = (card) ->
|
||||
card.map (x) ->
|
||||
x.load
|
||||
.reduce (y,z)->
|
||||
Math.max y,z
|
||||
|
||||
minLoad = (card) ->
|
||||
card.map (x) ->
|
||||
x.load
|
||||
.reduce (y,z)->
|
||||
Math.min y,z
|
||||
|
||||
getCardGraphOptions = (surface, downhole) ->
|
||||
limits =
|
||||
sMaxPos: minPos(surface) + 20
|
||||
sMinPos: maxPos(surface) - 20
|
||||
sMaxLoad: maxLoad(surface) + 2000
|
||||
sMinLoad: minLoad(surface) - 2000
|
||||
dMaxLoad: maxLoad(downhole) + 2000
|
||||
dMinLoad: minLoad(downhole) - 2000
|
||||
|
||||
|
||||
surfaceOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.sMinLoad,
|
||||
max: limits.sMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'surface',
|
||||
color: 'steelblue',
|
||||
type: ['line', 'area'],
|
||||
striped: true,
|
||||
label: 'Surface Card',
|
||||
id: "surfaceCard"
|
||||
}
|
||||
],
|
||||
grid: {
|
||||
x: true,
|
||||
y: true
|
||||
}
|
||||
};
|
||||
var downholeOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.dMinLoad,
|
||||
max: limits.dMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'downhole',
|
||||
color: 'steelblue',
|
||||
type: ['line', 'area'],
|
||||
label: 'Downhole Card',
|
||||
id: "downholeCard",
|
||||
}
|
||||
],
|
||||
grid: {
|
||||
x: true,
|
||||
y: true
|
||||
}
|
||||
};
|
||||
return({surf: surfaceOptions, down: downholeOptions});
|
||||
};
|
||||
|
||||
wellCtrls.factory('Page', function($log) {
|
||||
var title = 'default';
|
||||
var page = 'default';
|
||||
return {
|
||||
title: function() {
|
||||
return title;
|
||||
},
|
||||
setTitle: function(newTitle) {
|
||||
title = newTitle;
|
||||
},
|
||||
page: function() {
|
||||
return page;
|
||||
},
|
||||
setPage: function(newPage) {
|
||||
page = newPage;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
wellCtrls.factory('Alerts', function($log) {
|
||||
var alerts = [];
|
||||
return {
|
||||
add: function(alt) {
|
||||
alerts.push(alt);
|
||||
},
|
||||
remove: function(indx) {
|
||||
alerts.splice(indx, 1);
|
||||
},
|
||||
clear: function() {
|
||||
alerts = [];
|
||||
},
|
||||
get: function() {
|
||||
return alerts;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
wellCtrls.factory('json',function($q, $http, $log){
|
||||
var getDateList = function() {
|
||||
@@ -362,6 +481,48 @@ wellCtrls.factory('json',function($q, $http, $log){
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var getCurrentTagValues = function(){
|
||||
var deferred = $q.defer();
|
||||
$http.get('/json/tagvalues').success(function(data) {
|
||||
deferred.resolve({
|
||||
data: data
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var getTagsAtTime = function(unixTS){
|
||||
var deferred = $q.defer();
|
||||
$http.get('/json/tagvalues/' + unixTS).success(function(data) {
|
||||
deferred.resolve({
|
||||
data: data
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var getCurrentStatus = function(){
|
||||
var deferred = $q.defer();
|
||||
$http.get('/json/status').success(function(data) {
|
||||
deferred.resolve({
|
||||
data: data
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var getStatusAtTime = function(unixTS){
|
||||
var deferred = $q.defer();
|
||||
$http.get('/json/status/' + unixTS).success(function(data) {
|
||||
deferred.resolve({
|
||||
data: data
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
getDateList: getDateList,
|
||||
@@ -401,7 +562,14 @@ wellCtrls.factory('json',function($q, $http, $log){
|
||||
deleteWellTest: deleteWellTest,
|
||||
undeleteWellTest: undeleteWellTest,
|
||||
updateWellTest: updateWellTest,
|
||||
getDeletedWellTests: getDeletedWellTests
|
||||
getDeletedWellTests: getDeletedWellTests,
|
||||
|
||||
// Tag Data Functions
|
||||
getCurrentTagValues: getCurrentTagValues,
|
||||
getTagsAtTime: getTagsAtTime,
|
||||
|
||||
getCurrentStatus: getCurrentStatus,
|
||||
getStatusAtTime: getStatusAtTime
|
||||
};
|
||||
});
|
||||
|
||||
@@ -564,26 +732,39 @@ wellCtrls.controller('fileListTodayCtrl', function($scope, $http, $routeParams,
|
||||
wellCtrls.controller('dashboardCtrl', function($scope, $route, $http, $routeParams, json, Page, Alerts, $log) {
|
||||
Page.setTitle('Dashboard');
|
||||
Page.setPage('dashboard');
|
||||
// $scope.currentPage = 1;
|
||||
// $scope.numPerPage = 10;
|
||||
// $scope.maxSize = 9;
|
||||
$scope.dateListLoading = true;
|
||||
var getDateList = json.getDateList();
|
||||
getDateList.then(function(data) {
|
||||
$scope.dateListLoading = false;
|
||||
$scope.dates = data.dates;
|
||||
$scope.currentDate = $scope.dates[0];
|
||||
// $scope.numPages = function() {
|
||||
// return Math.ceil($scope.dates.length / $scope.numPerPage);
|
||||
// };
|
||||
// $scope.$watch('currentPage + numPerPage', function() {
|
||||
// var begin = ($scope.currentPage - 1) * $scope.numPerPage;
|
||||
// var end = begin + $scope.numPerPage;
|
||||
// $scope.filteredDates = $scope.dates.slice(begin, end);
|
||||
// });
|
||||
});
|
||||
$scope.dashboard = function() {
|
||||
$http.get('/json/latestCard').success(function(cData) {
|
||||
var getCurrentTagValues = json.getCurrentTagValues();
|
||||
getCurrentTagValues.then(function(d){
|
||||
var data = d.data;
|
||||
if (data.status == "OK"){
|
||||
$scope.tagValues = {};
|
||||
for(var i=0; i < data.vals.length; i++){
|
||||
$scope.tagValues[data.vals[i].name] = data.vals[i];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var getCurrentStatus = json.getCurrentStatus();
|
||||
getCurrentStatus.then(function(s){
|
||||
var sData = s.data;
|
||||
sData.datetime = new Date(sData.datetime * 1000);
|
||||
console.log(sData);
|
||||
|
||||
$scope.status = sData.run_status;
|
||||
$scope.status_datetime = new Date(sData.datetime);
|
||||
});
|
||||
|
||||
|
||||
var getLatestCard = json.getLatestCard();
|
||||
getLatestCard.then(function(cData){
|
||||
cData = cData.data;
|
||||
$scope.cardData = cData.card_data[0];
|
||||
//$scope.cardData.dateTime = new Date($scope.cardData.localtime.replace(" ","T"));
|
||||
|
||||
@@ -591,135 +772,27 @@ wellCtrls.controller('dashboardCtrl', function($scope, $route, $http, $routePara
|
||||
return {position:cData.card_data[0].Surface_Position[i], load:cData.card_data[0].Surface_Load[i]};
|
||||
});
|
||||
$scope.surface.push($scope.surface[0]);
|
||||
|
||||
$scope.downhole = cData.card_data[0].Downhole_Position.map(function(a, i){
|
||||
return {position:cData.card_data[0].Downhole_Position[i], load:cData.card_data[0].Downhole_Load[i]};
|
||||
});
|
||||
$scope.downhole.push($scope.downhole[0]);
|
||||
var limits = {
|
||||
sMaxPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.max(y,z);})+ 20,
|
||||
sMinPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.min(y,z);})- 20,
|
||||
sMaxLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
sMinLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
dMaxLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
dMinLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
};
|
||||
$scope.limits = limits;
|
||||
|
||||
$scope.card_graph_data = {
|
||||
surface: $scope.surface,
|
||||
downhole: $scope.downhole
|
||||
}
|
||||
|
||||
$scope.surfaceOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.sMinLoad,
|
||||
max: limits.sMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'surface',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Surface Card',
|
||||
id: "surfaceCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
},
|
||||
drawLegend: true,
|
||||
drawDots: true,
|
||||
columnsHGap: 5
|
||||
};
|
||||
$scope.downholeOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.dMinLoad,
|
||||
max: limits.dMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'downhole',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Downhole Card',
|
||||
id: "downholeCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
},
|
||||
drawLegend: true,
|
||||
drawDots: true,
|
||||
columnsHGap: 5
|
||||
};
|
||||
var graphOptions = getCardGraphOptions($scope.surface, $scope.downhole);
|
||||
$scope.surfaceOptions = graphOptions.surf;
|
||||
$scope.downholeOptions = graphOptions.down;
|
||||
});
|
||||
|
||||
var statusMap = {
|
||||
0:"Stopped",
|
||||
1:"Running",
|
||||
2:"Pumped Off",
|
||||
3:"Faulted",
|
||||
4:"Starting",
|
||||
5:"Recovering",
|
||||
100:"Read Error",
|
||||
9999:"PLC Error"
|
||||
};
|
||||
$http.get('/json/status/').success(function(data) {
|
||||
$scope.wellStatus = statusMap[parseInt(data.status)];
|
||||
var sDt = new Date(data.date);
|
||||
});
|
||||
var getTotals = json.getTotals();
|
||||
getTotals.then(function(data){
|
||||
$scope.totals = data.totals;
|
||||
});
|
||||
};
|
||||
$scope.dashboard();
|
||||
// socket.on('notification', function(data) {
|
||||
// $scope.dashboard();
|
||||
// });
|
||||
});
|
||||
|
||||
wellCtrls.controller('totalsCtrl', function($scope, json, Page, $log){
|
||||
@@ -755,7 +828,7 @@ wellCtrls.controller('totalsCtrl', function($scope, json, Page, $log){
|
||||
$scope.refresh();
|
||||
});
|
||||
|
||||
wellCtrls.controller('cardDataCtrl', function($scope, $http, $routeParams, json, Page) {
|
||||
wellCtrls.controller('cardDataCtrl', function($scope, $http, $routeParams, json, Page, $log) {
|
||||
$scope.loading = true;
|
||||
Page.setTitle('Card Data');
|
||||
Page.setPage('cardData');
|
||||
@@ -765,119 +838,43 @@ wellCtrls.controller('cardDataCtrl', function($scope, $http, $routeParams, json,
|
||||
$scope.dates = data.dates;
|
||||
$scope.currentDate = $scope.dates[0];
|
||||
});
|
||||
$http.get('/json/card/' + $routeParams.id).success(function(cData) {
|
||||
if (cData.error){
|
||||
$scope.error = cData.error;
|
||||
$scope.loading = false;
|
||||
} else {
|
||||
$scope.cardData = cData.card_data;
|
||||
//$scope.cardData.dateTime = new Date($scope.cardData.localtime.replace(" ","T"));
|
||||
|
||||
$scope.surface = cData.card_data.Surface_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Surface_Position[i], load:cData.card_data.Surface_Load[i]};
|
||||
});
|
||||
$scope.surface.push($scope.surface[0]);
|
||||
$scope.downhole = cData.card_data.Downhole_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Downhole_Position[i], load:cData.card_data.Downhole_Load[i]};
|
||||
});
|
||||
$scope.downhole.push($scope.downhole[0]);
|
||||
var limits = {
|
||||
sMaxPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.max(y,z);})+ 20,
|
||||
sMinPos: $scope.surface.map(function(x){return x.position;}).reduce(function(y,z){return Math.min(y,z);})- 20,
|
||||
sMaxLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
sMinLoad: $scope.surface.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
dMaxLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.max(y,z);})+ 2000,
|
||||
dMinLoad: $scope.downhole.map(function(x){return x.load;}).reduce(function(y,z){return Math.min(y,z);})- 2000,
|
||||
};
|
||||
$scope.limits = limits;
|
||||
$scope.card_graph_data = {
|
||||
surface: $scope.surface,
|
||||
downhole: $scope.downhole
|
||||
}
|
||||
var getCard = json.getCard($routeParams.id);
|
||||
getCard.then(function(cData){
|
||||
cData = cData.data;
|
||||
$scope.cardData = cData.card_data;
|
||||
$scope.cardData.Stroke_Time = new Date($scope.cardData.Stroke_Time);
|
||||
//$scope.cardData.dateTime = new Date($scope.cardData.localtime.replace(" ","T"));
|
||||
|
||||
$scope.surfaceOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.sMinLoad,
|
||||
max: limits.sMaxLoad
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'surface',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Surface Card',
|
||||
id: "surfaceCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
$scope.surface = cData.card_data.Surface_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Surface_Position[i], load:cData.card_data.Surface_Load[i]};
|
||||
});
|
||||
$scope.surface.push($scope.surface[0]);
|
||||
|
||||
$scope.downhole = cData.card_data.Downhole_Position.map(function(a, i){
|
||||
return {position:cData.card_data.Downhole_Position[i], load:cData.card_data.Downhole_Load[i]};
|
||||
});
|
||||
$scope.downhole.push($scope.downhole[0]);
|
||||
|
||||
$scope.card_graph_data = {
|
||||
surface: $scope.surface,
|
||||
downhole: $scope.downhole
|
||||
};
|
||||
var graphOptions = getCardGraphOptions($scope.surface, $scope.downhole);
|
||||
$scope.surfaceOptions = graphOptions.surf;
|
||||
$scope.downholeOptions = graphOptions.down;
|
||||
|
||||
var getTagsAtTime = json.getTagsAtTime($scope.cardData.Stroke_Time.getTime() / 1000);
|
||||
getTagsAtTime.then(function(d){
|
||||
var data = d.data;
|
||||
if (data.status == "OK"){
|
||||
$scope.loading = false;
|
||||
$scope.tagData = {};
|
||||
for(var i=0; i < data.vals.length; i++){
|
||||
$scope.tagData[data.vals[i].name] = data.vals[i];
|
||||
}
|
||||
};
|
||||
$scope.downholeOptions = {
|
||||
axes: {
|
||||
x: {
|
||||
key: 'position',
|
||||
labelFunction: function(value) {
|
||||
return value;
|
||||
},
|
||||
type: 'linear',
|
||||
min: limits.sMinPos,
|
||||
max: limits.sMaxPos,
|
||||
ticks: 7
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
min: limits.dMinLoad,
|
||||
max: limits.dMaxLoad,
|
||||
ticks: 5
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
axis:"y",
|
||||
key: 'load',
|
||||
dataset: 'downhole',
|
||||
color: 'steelblue',
|
||||
type: 'area',
|
||||
striped: true,
|
||||
label: 'Downhole Card',
|
||||
id: "downholeCard"
|
||||
}
|
||||
],
|
||||
lineMode: 'linear',
|
||||
tension: 0.7,
|
||||
tooltip: {
|
||||
mode: 'scrubber',
|
||||
formatter: function(x, y, series) {
|
||||
return 'Position: ' + x + ' in., Load: ' + y + ' lb.';
|
||||
}
|
||||
},
|
||||
drawLegend: true,
|
||||
drawDots: true,
|
||||
columnsHGap: 5
|
||||
};
|
||||
$scope.loading = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1360,6 +1360,7 @@ exports.getValuesClosestTo = (req, res) ->
|
||||
console.log errMsg
|
||||
res.json errMsg
|
||||
else
|
||||
# query2 = "SELECT name, AVG(found_tags.val) AS avgval, MAX(dtime) AS after, MIN(dtime) AS before FROM ( SELECT name, val, dtime FROM tag_vals WHERE name = ? ORDER BY abs(dtime - ?) LIMIT 2) found_tags"
|
||||
res.json
|
||||
status: "OK"
|
||||
vals: rows
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
<script src='/bower_components/justgage-toorshia/justgage.js'></script>
|
||||
<script src='/bower_components/angular-justgage/ng-justgage.js'></script>
|
||||
<script src="/node_modules/n3-charts/node_modules/d3/d3.min.js"></script>
|
||||
<script src="/node_modules/n3-charts/build/LineChart.js"></script>
|
||||
<script src="/node_modules/n3-charts/build/LineChart.js"></script>
|
||||
<link rel="stylesheet" href="/node_modules/n3-charts/build/LineChart.css">
|
||||
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src='/bower_components/bootstrap/dist/js/bootstrap.js'></script>
|
||||
|
||||
Reference in New Issue
Block a user