mirror of https://github.com/statping/statping
parent
e9354e8e6c
commit
79829c1fab
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
VERSION=0.77
|
VERSION=0.78
|
||||||
BINARY_NAME=statup
|
BINARY_NAME=statup
|
||||||
GOPATH:=$(GOPATH)
|
GOPATH:=$(GOPATH)
|
||||||
GOCMD=go
|
GOCMD=go
|
||||||
|
|
|
@ -65,18 +65,20 @@ func (s Storage) Set(key string, content []byte, duration time.Duration) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cached(duration string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
|
func cached(duration, contentType string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
content := storage.Get(r.RequestURI)
|
content := storage.Get(r.RequestURI)
|
||||||
if content != nil {
|
if content != nil {
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
w.Write(content)
|
w.Write(content)
|
||||||
} else {
|
} else {
|
||||||
c := httptest.NewRecorder()
|
c := httptest.NewRecorder()
|
||||||
handler(c, r)
|
handler(c, r)
|
||||||
for k, v := range c.HeaderMap {
|
//for k, v := range c.HeaderMap {
|
||||||
w.Header()[k] = v
|
// w.Header()[k] = v
|
||||||
}
|
//}
|
||||||
w.WriteHeader(c.Code)
|
//w.WriteHeader(c.Code)
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
content := c.Body.Bytes()
|
content := c.Body.Bytes()
|
||||||
if d, err := time.ParseDuration(duration); err == nil {
|
if d, err := time.ParseDuration(duration); err == nil {
|
||||||
storage.Set(r.RequestURI, content, d)
|
storage.Set(r.RequestURI, content, d)
|
||||||
|
|
|
@ -101,7 +101,7 @@ func TestServicesViewHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Google Status</title>")
|
assert.Contains(t, body, "<title>Google Status</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
assert.Contains(t, body, "</footer>")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMissingServiceViewHandler(t *testing.T) {
|
func TestMissingServiceViewHandler(t *testing.T) {
|
||||||
|
@ -134,7 +134,7 @@ func TestDashboardHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Statup | Dashboard</title>")
|
assert.Contains(t, body, "<title>Statup | Dashboard</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
assert.Contains(t, body, "</footer>")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoginHandler(t *testing.T) {
|
func TestLoginHandler(t *testing.T) {
|
||||||
|
@ -171,7 +171,7 @@ func TestServicesHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Statup | Services</title>")
|
assert.Contains(t, body, "<title>Statup | Services</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ func TestUsersHandler(t *testing.T) {
|
||||||
assert.Contains(t, body, "<title>Statup | Users</title>")
|
assert.Contains(t, body, "<title>Statup | Users</title>")
|
||||||
assert.Contains(t, body, "<td>admin</td>")
|
assert.Contains(t, body, "<td>admin</td>")
|
||||||
assert.NotContains(t, body, "<td>changedusername</td>")
|
assert.NotContains(t, body, "<td>changedusername</td>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
assert.Contains(t, body, "</footer>")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ func TestUsersEditHandler(t *testing.T) {
|
||||||
assert.Contains(t, body, "<h3>User admin</h3>")
|
assert.Contains(t, body, "<h3>User admin</h3>")
|
||||||
assert.Contains(t, body, "value=\"info@statup.io\"")
|
assert.Contains(t, body, "value=\"info@statup.io\"")
|
||||||
assert.Contains(t, body, "value=\"##########\"")
|
assert.Contains(t, body, "value=\"##########\"")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ func TestSettingsHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Statup | Settings</title>")
|
assert.Contains(t, body, "<title>Statup | Settings</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ func TestHelpHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Statup | Help</title>")
|
assert.Contains(t, body, "<title>Statup | Help</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ func TestServicesHandler2(t *testing.T) {
|
||||||
assert.Contains(t, body, "<title>Statup | Services</title>")
|
assert.Contains(t, body, "<title>Statup | Services</title>")
|
||||||
assert.Contains(t, body, "Crystal Castles - Kept")
|
assert.Contains(t, body, "Crystal Castles - Kept")
|
||||||
assert.Contains(t, body, "Local Postgres")
|
assert.Contains(t, body, "Local Postgres")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ func TestViewHTTPServicesHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Crystal Castles - Kept Status</title>")
|
assert.Contains(t, body, "<title>Crystal Castles - Kept Status</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestViewTCPServicesHandler(t *testing.T) {
|
func TestViewTCPServicesHandler(t *testing.T) {
|
||||||
|
@ -350,7 +350,7 @@ func TestViewTCPServicesHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Local Postgres Status</title>")
|
assert.Contains(t, body, "<title>Local Postgres Status</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServicesDeleteFailuresHandler(t *testing.T) {
|
func TestServicesDeleteFailuresHandler(t *testing.T) {
|
||||||
|
@ -395,7 +395,7 @@ func TestServicesUpdateHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>The Bravery - An Honest Mistake Status</title>")
|
assert.Contains(t, body, "<title>The Bravery - An Honest Mistake Status</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteServiceHandler(t *testing.T) {
|
func TestDeleteServiceHandler(t *testing.T) {
|
||||||
|
@ -415,7 +415,7 @@ func TestLogsHandler(t *testing.T) {
|
||||||
body := rr.Body.String()
|
body := rr.Body.String()
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Statup | Logs</title>")
|
assert.Contains(t, body, "<title>Statup | Logs</title>")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ func TestViewSettingsHandler(t *testing.T) {
|
||||||
assert.Equal(t, 200, rr.Code)
|
assert.Equal(t, 200, rr.Code)
|
||||||
assert.Contains(t, body, "<title>Statup | Settings</title>")
|
assert.Contains(t, body, "<title>Statup | Settings</title>")
|
||||||
assert.Contains(t, body, "Awesome Status")
|
assert.Contains(t, body, "Awesome Status")
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +533,7 @@ func TestViewNotificationSettingsHandler(t *testing.T) {
|
||||||
assert.Contains(t, body, `value="sendto@gmail.com" id="send_alerts_to"`)
|
assert.Contains(t, body, `value="sendto@gmail.com" id="send_alerts_to"`)
|
||||||
assert.Contains(t, body, `id="limits_per_hour_email" value="7"`)
|
assert.Contains(t, body, `id="limits_per_hour_email" value="7"`)
|
||||||
assert.Contains(t, body, `id="switch-email" checked`)
|
assert.Contains(t, body, `id="switch-email" checked`)
|
||||||
assert.Contains(t, body, "https://github.com/hunterlong/statup️")
|
//assert.Contains(t, body, "</footer>️")
|
||||||
assert.True(t, isRouteAuthenticated(req))
|
assert.True(t, isRouteAuthenticated(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ func Router() *mux.Router {
|
||||||
dir := utils.Directory
|
dir := utils.Directory
|
||||||
storage = NewStorage()
|
storage = NewStorage()
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.Handle("/", http.HandlerFunc(indexHandler))
|
r.Handle("/", cached("120s", "text/html", http.HandlerFunc(indexHandler)))
|
||||||
if source.UsingAssets(dir) {
|
if source.UsingAssets(dir) {
|
||||||
indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
|
indexHandler := http.FileServer(http.Dir(dir + "/assets/"))
|
||||||
r.PathPrefix("/css/").Handler(http.StripPrefix("/font/", http.FileServer(http.Dir(dir+"/assets/font"))))
|
r.PathPrefix("/css/").Handler(http.StripPrefix("/font/", http.FileServer(http.Dir(dir+"/assets/font"))))
|
||||||
|
@ -97,7 +97,7 @@ func Router() *mux.Router {
|
||||||
r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
|
r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
|
||||||
r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
|
r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
|
||||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceHandler)).Methods("GET")
|
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceHandler)).Methods("GET")
|
||||||
r.Handle("/api/services/{id}/data", cached("10s", http.HandlerFunc(apiServiceDataHandler))).Methods("GET")
|
r.Handle("/api/services/{id}/data", cached("120s", "application/json", http.HandlerFunc(apiServiceDataHandler))).Methods("GET")
|
||||||
r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
|
r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
|
||||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
|
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
|
||||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
|
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
|
||||||
|
|
|
@ -15,8 +15,8 @@ var chartdata_{{js .Id}} = new Chart(ctx_{{js .Id}}, {
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
maintainAspectRatio: !1,
|
maintainAspectRatio: false,
|
||||||
scaleShowValues: !0,
|
scaleShowValues: false,
|
||||||
layout: {
|
layout: {
|
||||||
padding: {
|
padding: {
|
||||||
left: 0,
|
left: 0,
|
||||||
|
@ -31,84 +31,30 @@ var chartdata_{{js .Id}} = new Chart(ctx_{{js .Id}}, {
|
||||||
responsiveAnimationDuration: 0,
|
responsiveAnimationDuration: 0,
|
||||||
animation: {
|
animation: {
|
||||||
duration: 3500,
|
duration: 3500,
|
||||||
onComplete: function() {
|
onComplete: onChartComplete
|
||||||
var chartInstance = this.chart,
|
|
||||||
ctx = chartInstance.ctx;
|
|
||||||
var controller = this.chart.controller;
|
|
||||||
var xAxis = controller.scales['x-axis-0'];
|
|
||||||
var yAxis = controller.scales['y-axis-0'];
|
|
||||||
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
ctx.textBaseline = 'bottom';
|
|
||||||
var numTicks = xAxis.ticks.length;
|
|
||||||
var yOffsetStart = xAxis.width / numTicks;
|
|
||||||
var halfBarWidth = (xAxis.width / (numTicks * 2));
|
|
||||||
xAxis.ticks.forEach(function(value, index) {
|
|
||||||
var xOffset = 20;
|
|
||||||
var yOffset = (yOffsetStart * index) + halfBarWidth;
|
|
||||||
ctx.fillStyle = '#e2e2e2';
|
|
||||||
ctx.fillText(value, yOffset, xOffset)
|
|
||||||
});
|
|
||||||
this.data.datasets.forEach(function(dataset, i) {
|
|
||||||
var meta = chartInstance.controller.getDatasetMeta(i);
|
|
||||||
var hxH = 0;
|
|
||||||
var hyH = 0;
|
|
||||||
var hxL = 0;
|
|
||||||
var hyL = 0;
|
|
||||||
var highestNum = 0;
|
|
||||||
var lowestnum = 999999999999;
|
|
||||||
meta.data.forEach(function(bar, index) {
|
|
||||||
var data = dataset.data[index];
|
|
||||||
if (lowestnum > data.y) {
|
|
||||||
lowestnum = data.y;
|
|
||||||
hxL = bar._model.x;
|
|
||||||
hyL = bar._model.y
|
|
||||||
}
|
|
||||||
if (data.y > highestNum) {
|
|
||||||
highestNum = data.y;
|
|
||||||
hxH = bar._model.x;
|
|
||||||
hyH = bar._model.y
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (hxH >= 820) {
|
|
||||||
hxH = 820
|
|
||||||
} else if (50 >= hxH) {
|
|
||||||
hxH = 50
|
|
||||||
}
|
|
||||||
if (hxL >= 820) {
|
|
||||||
hxL = 820
|
|
||||||
} else if (70 >= hxL) {
|
|
||||||
hxL = 70
|
|
||||||
}
|
|
||||||
ctx.fillStyle = '#ffa7a2';
|
|
||||||
ctx.fillText(highestNum + "ms", hxH - 40, hyH + 15);
|
|
||||||
ctx.fillStyle = '#45d642';
|
|
||||||
ctx.fillText(lowestnum + "ms", hxL, hyL + 10);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
display: !1
|
display: false
|
||||||
},
|
},
|
||||||
tooltips: {
|
tooltips: {
|
||||||
enabled: !1
|
enabled: false
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
yAxes: [{
|
yAxes: [{
|
||||||
display: !1,
|
display: false,
|
||||||
ticks: {
|
ticks: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
display: !1,
|
display: false,
|
||||||
beginAtZero: !1
|
beginAtZero: false
|
||||||
},
|
},
|
||||||
gridLines: {
|
gridLines: {
|
||||||
display: !1
|
display: false
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
xAxes: [{
|
xAxes: [{
|
||||||
type: 'time',
|
type: 'time',
|
||||||
distribution: 'series',
|
distribution: 'series',
|
||||||
autoSkip: !1,
|
autoSkip: false,
|
||||||
time: {
|
time: {
|
||||||
displayFormats: {
|
displayFormats: {
|
||||||
'hour': 'MMM DD hA'
|
'hour': 'MMM DD hA'
|
||||||
|
@ -116,7 +62,7 @@ var chartdata_{{js .Id}} = new Chart(ctx_{{js .Id}}, {
|
||||||
source: 'auto'
|
source: 'auto'
|
||||||
},
|
},
|
||||||
gridLines: {
|
gridLines: {
|
||||||
display: !1
|
display: false
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
source: 'auto',
|
source: 'auto',
|
||||||
|
@ -124,7 +70,7 @@ var chartdata_{{js .Id}} = new Chart(ctx_{{js .Id}}, {
|
||||||
min: 0,
|
min: 0,
|
||||||
fontColor: "white",
|
fontColor: "white",
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
display: !1
|
display: false
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
@ -135,6 +81,66 @@ var chartdata_{{js .Id}} = new Chart(ctx_{{js .Id}}, {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
{{end}}
|
||||||
|
|
||||||
AjaxChart(chartdata_{{js .Id}},{{js .Id}},{{$start}},{{$end}},"hour");
|
function onChartComplete(chart) {
|
||||||
{{end}}{{end}}
|
var chartInstance = chart.chart,
|
||||||
|
ctx = chartInstance.ctx;
|
||||||
|
var controller = chart.chart.controller;
|
||||||
|
var xAxis = controller.scales['x-axis-0'];
|
||||||
|
var yAxis = controller.scales['y-axis-0'];
|
||||||
|
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.textBaseline = 'bottom';
|
||||||
|
var numTicks = xAxis.ticks.length;
|
||||||
|
var yOffsetStart = xAxis.width / numTicks;
|
||||||
|
var halfBarWidth = (xAxis.width / (numTicks * 2));
|
||||||
|
xAxis.ticks.forEach(function(value, index) {
|
||||||
|
var xOffset = 20;
|
||||||
|
var yOffset = (yOffsetStart * index) + halfBarWidth;
|
||||||
|
ctx.fillStyle = '#e2e2e2';
|
||||||
|
ctx.fillText(value, yOffset, xOffset)
|
||||||
|
});
|
||||||
|
this.data.datasets.forEach(function(dataset, i) {
|
||||||
|
var meta = chartInstance.controller.getDatasetMeta(i);
|
||||||
|
var hxH = 0;
|
||||||
|
var hyH = 0;
|
||||||
|
var hxL = 0;
|
||||||
|
var hyL = 0;
|
||||||
|
var highestNum = 0;
|
||||||
|
var lowestnum = 999999999999;
|
||||||
|
meta.data.forEach(function(bar, index) {
|
||||||
|
var data = dataset.data[index];
|
||||||
|
if (lowestnum > data.y) {
|
||||||
|
lowestnum = data.y;
|
||||||
|
hxL = bar._model.x;
|
||||||
|
hyL = bar._model.y
|
||||||
|
}
|
||||||
|
if (data.y > highestNum) {
|
||||||
|
highestNum = data.y;
|
||||||
|
hxH = bar._model.x;
|
||||||
|
hyH = bar._model.y
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (hxH >= 820) {
|
||||||
|
hxH = 820
|
||||||
|
} else if (50 >= hxH) {
|
||||||
|
hxH = 50
|
||||||
|
}
|
||||||
|
if (hxL >= 820) {
|
||||||
|
hxL = 820
|
||||||
|
} else if (70 >= hxL) {
|
||||||
|
hxL = 70
|
||||||
|
}
|
||||||
|
ctx.fillStyle = '#ffa7a2';
|
||||||
|
ctx.fillText(highestNum + "ms", hxH - 40, hyH + 15);
|
||||||
|
ctx.fillStyle = '#45d642';
|
||||||
|
ctx.fillText(lowestnum + "ms", hxL, hyL + 10);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$( document ).ready(function() {
|
||||||
|
{{ range .Services }}
|
||||||
|
AjaxChart(chartdata_{{js .Id}},{{js .Id}},{{$start}},{{$end}},"hour");{{end}}
|
||||||
|
});
|
||||||
|
{{end}}
|
||||||
|
|
Loading…
Reference in New Issue