mirror of
https://github.com/timberjoegithub/grafana-statusmap.git
synced 2026-07-21 23:42:03 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bccc3320a8 | ||
|
|
5d7cf54348 | ||
|
|
1f43ffe158 | ||
|
|
c7882402ce | ||
|
|
09cdd2f224 | ||
|
|
0a8463e2ed | ||
|
|
4d952a841b | ||
|
|
36e907f8b6 | ||
|
|
af55883905 | ||
|
|
afec01cb93 |
@@ -1,2 +1,4 @@
|
||||
node_modules
|
||||
.jshintrc
|
||||
.idea
|
||||
.sass-cache
|
||||
|
||||
+2
-1
@@ -53,7 +53,8 @@ module.exports = (grunt) => {
|
||||
sass: {
|
||||
dist: {
|
||||
files: {
|
||||
'dist/css/status-heatmap.css': 'src/css/status-heatmap.scss'
|
||||
'dist/css/statusmap.dark.css': 'src/css/statusmap.dark.scss',
|
||||
'dist/css/statusmap.light.css': 'src/css/statusmap.light.scss'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* Grouping values into rows and buckets using legend from query
|
||||
* User defined color mapping
|
||||
* Multiple values in bucket can be displayed via tooltip
|
||||
* Multiple values in bucket are displayed via tooltip
|
||||
* Increasing rows/buckets' interval for better visual representation
|
||||
* Representing null values as empty bucket or zero value
|
||||
|
||||
@@ -17,7 +20,7 @@
|
||||
|
||||
## Installation
|
||||
|
||||
Plugin can be installed via Git:
|
||||
Plugin can be installed with GF_INSTALL_PLUGINS="flant-statusmap-panel" or you can use Git and clone this repo:
|
||||
|
||||
```
|
||||
git clone git@github.com:flant/grafana-statusmap.git /var/lib/grafana/plugins/flant-statusmap-panel
|
||||
@@ -26,15 +29,19 @@ git clone git@github.com:flant/grafana-statusmap.git /var/lib/grafana/plugins/fl
|
||||
Alternatively, you can download [ZIP archive](https://github.com/flant/grafana-statusmap/archive/master.zip)
|
||||
of this repo and unpack it into /var/lib/grafana/plugins directory.
|
||||
|
||||
|
||||
## Motivation
|
||||
|
||||
We had a desperate need to show a set of timeseries statuses over time period, so we can see
|
||||
a history of changes for objects' statuses. Since we maintain a lot of Kubernetes clusters
|
||||
We had a desperate need to visualize a set of timeseries statuses over time period, so we can
|
||||
see a history of changes for objects' status. Since we maintain a lot of Kubernetes clusters
|
||||
(and related infrastructure), our main cases for that are visualization of servers & Kubernetes
|
||||
pods health states as well as HTTP services health checks. We've tried a variety of Grafana
|
||||
plugins available (they are listed in *Acknowledgements* below) but none of them could provide
|
||||
the features and visualization really close to what we've been looking for.
|
||||
|
||||
_NB: You can find more details about our journey of creating the plugin in
|
||||
[this post](https://medium.com/flant-com/statusmap-grafana-plugin-to-visualize-status-over-time-fe6ced391853)._
|
||||
|
||||
_Objects_ being visualized with this plugin may be different: not only IT components (e.g. server
|
||||
hosts and Kubernetes pods) but just anything you can imagine like coffee makers on the picture
|
||||
above. These objects should have _discrete statuses_ which are sets of predefined values, e.g.
|
||||
@@ -44,7 +51,7 @@ above. These objects should have _discrete statuses_ which are sets of predefine
|
||||
|
||||
### Prometheus
|
||||
|
||||
To work with data from Prometheus you will need to setup discrete statuses of your objects.
|
||||
To work with data from Prometheus you will need to setup discrete statuses for your objects.
|
||||
Requirements to store these statuses in metrics are as follows:
|
||||
* metrics should have two values: `0` and `1`;
|
||||
* there should be a label with status' value.
|
||||
@@ -58,8 +65,8 @@ When it's done, you can collect all the data via query, e.g.:
|
||||
If there was no such status (`<STATUS_VALUE>`) during query's interval, Prometheus would
|
||||
return nothing. Otherwise, status' value will be returned.
|
||||
|
||||
For example, if you have 5 statuses and a metric (`coffee_maker_status`) with 5 allowed
|
||||
values (`0`, `1`, `2`, `3`, `4`), you should transform this metric using the following rule:
|
||||
For example, if you have 5 types of statuses and a metric (`coffee_maker_status`) with 5
|
||||
allowed values (`0`, `1`, `2`, `3`, `4`), you should transform this metric using following rule:
|
||||
|
||||
```
|
||||
- record: coffee_maker_status:discrete
|
||||
@@ -137,7 +144,13 @@ This plugin is based on "Heatmap" panel by Grafana and partly inspired by ideas
|
||||
|
||||
#### Changelog
|
||||
|
||||
##### v0.0.2
|
||||
|
||||
- Install with GF_INSTALL_PLUGINS
|
||||
- Fix legend overlap
|
||||
|
||||
##### v0.0.1
|
||||
|
||||
- First public release
|
||||
|
||||
|
||||
|
||||
Vendored
+83
-25
@@ -2,13 +2,16 @@
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* Group values into rows and buckets by query's legend
|
||||
* Grouping values into rows and buckets using legend from query
|
||||
* User defined color mapping
|
||||
* Multiple values in bucket display in tooltip
|
||||
* Interval shaping to better visual representation
|
||||
* Represent null values as empty bucket or as zero value
|
||||
* Multiple values in bucket are displayed via tooltip
|
||||
* Increasing rows/buckets' interval for better visual representation
|
||||
* Representing null values as empty bucket or zero value
|
||||
|
||||
### Supported environment
|
||||
|
||||
@@ -17,59 +20,107 @@
|
||||
|
||||
## Installation
|
||||
|
||||
Plugin can be installed with git:
|
||||
Plugin can be installed with GF_INSTALL_PLUGINS="flant-statusmap-panel" or you can use Git and clone this repo:
|
||||
|
||||
```
|
||||
git clone git@github.com:flant/grafana-statusmap.git /var/lib/grafana/plugins/flant-statusmap-panel
|
||||
```
|
||||
|
||||
Or you can download ZIP archive of this repo and unpack it into /var/lib/grafana/plugins directory.
|
||||
Alternatively, you can download [ZIP archive](https://github.com/flant/grafana-statusmap/archive/master.zip)
|
||||
of this repo and unpack it into /var/lib/grafana/plugins directory.
|
||||
|
||||
|
||||
## Motivation
|
||||
|
||||
This plugin emerges from our needs to visually represent history of changes for a set of objects
|
||||
with discrete statuses.
|
||||
_Objects_ can be hosts, Kubernetes pods or coffee makers and _discrete statuses_ are a set
|
||||
of predefined values: something like `ok` = 0, `off` = 1, `fail` = 2.
|
||||
We had a desperate need to visualize a set of timeseries statuses over time period, so we can
|
||||
see a history of changes for objects' status. Since we maintain a lot of Kubernetes clusters
|
||||
(and related infrastructure), our main cases for that are visualization of servers & Kubernetes
|
||||
pods health states as well as HTTP services health checks. We've tried a variety of Grafana
|
||||
plugins available (they are listed in *Acknowledgements* below) but none of them could provide
|
||||
the features and visualization really close to what we've been looking for.
|
||||
|
||||
_NB: You can find more details about our journey of creating the plugin in
|
||||
[this post](https://medium.com/flant-com/statusmap-grafana-plugin-to-visualize-status-over-time-fe6ced391853)._
|
||||
|
||||
_Objects_ being visualized with this plugin may be different: not only IT components (e.g. server
|
||||
hosts and Kubernetes pods) but just anything you can imagine like coffee makers on the picture
|
||||
above. These objects should have _discrete statuses_ which are sets of predefined values, e.g.
|
||||
`ok` = 0, `off` = 1, `fail` = 2, etc.
|
||||
|
||||
## Configuration
|
||||
|
||||
Recommended setup is to create query for each possible status value with similar legend:
|
||||
### Prometheus
|
||||
|
||||
To work with data from Prometheus you will need to setup discrete statuses for your objects.
|
||||
Requirements to store these statuses in metrics are as follows:
|
||||
* metrics should have two values: `0` and `1`;
|
||||
* there should be a label with status' value.
|
||||
|
||||
When it's done, you can collect all the data via query, e.g.:
|
||||
|
||||
```
|
||||
(max_over_time(coffee_maker_status{status="<STATUS_VALUE>"}[$__interval]) == 1) * <STATUS_VALUE>
|
||||
```
|
||||
|
||||
If there was no such status (`<STATUS_VALUE>`) during query's interval, Prometheus would
|
||||
return nothing. Otherwise, status' value will be returned.
|
||||
|
||||
For example, if you have 5 types of statuses and a metric (`coffee_maker_status`) with 5
|
||||
allowed values (`0`, `1`, `2`, `3`, `4`), you should transform this metric using following rule:
|
||||
|
||||
```
|
||||
- record: coffee_maker_status:discrete
|
||||
expr: |
|
||||
count_values("status", coffee_maker_status)
|
||||
```
|
||||
|
||||
That's how `coffee_maker_status` metric with value `3` will be transformed into new metric:
|
||||
|
||||
```
|
||||
coffee_maker_status:discrete{status="3"} 1
|
||||
```
|
||||
|
||||
Now, when Prometheus has `0` and `1` values for each status, all these metrics can be
|
||||
aggregated, so you will get all available statuses of your objects over time.
|
||||
|
||||
### Panel
|
||||
|
||||
First of all, an individual query for each possible status' value should be created.
|
||||
Each query should also have similar legend for grouping:
|
||||
|
||||

|
||||
|
||||
Next define color mapping for status values in __Discrete__ color mode.
|
||||
Then, color mapping for status' values should be defined in __Discrete__ color mode:
|
||||
|
||||

|
||||
|
||||
|
||||
__Spectrum__ and __Opacity__ color modes works as in a [Heatmap](https://grafana.com/plugins/heatmap) plugin.
|
||||
_Note: __Spectrum__ and __Opacity__ color modes function the same way they do in [Heatmap](https://grafana.com/plugins/heatmap) plugin._
|
||||
|
||||
|
||||
### More options
|
||||
|
||||

|
||||
|
||||
__Multiple values__ check determine multiple values display mode. If check is unset then multiple values
|
||||
for one bucket treated as error. If check is on then color for bucket determined
|
||||
by value with least index in color mapping.
|
||||
__Multiple values__ checkbox specifies how they should be displayed:
|
||||
* If it's off, multiple values for one bucket are treated as error;
|
||||
* If it's on, color for such bucket would be determined by the value having least index in color mapping.
|
||||
|
||||

|
||||
|
||||
__Null values__ can be treated as empty buckets or displayed as color of 0 value.
|
||||
__Null values__ can be treated as empty buckets or displayed with the color of `0` value.
|
||||
|
||||

|
||||
|
||||
__Min width__ and __spacing__ are determine minimal bucket width and spacing between buckets.
|
||||
__Rounding__ is for round edges.
|
||||
__Min width__ and __spacing__ are used to specify minimal bucket width and spacing between buckets.
|
||||
__Rounding__ may be used to round edges.
|
||||
|
||||

|
||||
|
||||
|
||||
## Development
|
||||
|
||||
The easy way to test and develop plugin is to run Grafana instance in docker with following command in the directory containing the plugin.
|
||||
This will expose the local plugin on your machine to the Grafana container.
|
||||
To test and improve the plugin you can run Grafana instance in Docker using following command (in
|
||||
the directory containing Statusmap plugin):
|
||||
|
||||
```
|
||||
docker run --rm -it -v $PWD:/var/lib/grafana/plugins/flant-statusmap-panel \
|
||||
@@ -78,7 +129,8 @@ docker run --rm -it -v $PWD:/var/lib/grafana/plugins/flant-statusmap-panel \
|
||||
grafana/grafana:5.1.3
|
||||
```
|
||||
|
||||
Now run `grunt` to compile dist directory and start changes watcher:
|
||||
This will expose local plugin from your machine to Grafana container. Now run `grunt` to compile
|
||||
dist directory and start changes watcher:
|
||||
|
||||
```
|
||||
grunt watch
|
||||
@@ -86,13 +138,19 @@ grunt watch
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Idea of a plugin comes from Dmitry Stolyarov @distol, initial version written by Sergey Gnuskov @gsmetal and final changes made by Ivan Mikheykin @diafour.
|
||||
The first public release of this plugin has been fully made by [Flant](https://flant.com/) engineers. The whole idea has come from Dmitry Stolyarov ([@distol](https://github.com/distol)), initial version has been written by Sergey Gnuskov ([@gsmetal](https://github.com/gsmetal)) and final changes has been made by Ivan Mikheykin ([@diafour](https://github.com/diafour)).
|
||||
|
||||
This plugin is based on a "Heatmap" panel by Grafana and inspired by ideas from Carpet plot, Discrete panel, Status Panel, Status Dot, Status By Group.
|
||||
This plugin is based on "Heatmap" panel by Grafana and partly inspired by ideas from Carpet plot, Discrete panel, Status Panel, Status Dot, Status By Group.
|
||||
|
||||
#### Changelog
|
||||
|
||||
##### v0.0.2
|
||||
|
||||
- Install with GF_INSTALL_PLUGINS
|
||||
- Fix legend overlap
|
||||
|
||||
##### v0.0.1
|
||||
|
||||
- First public release
|
||||
|
||||
|
||||
|
||||
Vendored
+8
-6
@@ -10,7 +10,7 @@ System.register(['angular', 'lodash', 'jquery', 'd3', './libs/d3-scale-chromatic
|
||||
var legend = d3.select(legendElem.get(0));
|
||||
clearLegend(elem);
|
||||
|
||||
var legendWidth = Math.floor(legendElem.outerWidth()) - 30;
|
||||
var legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values
|
||||
var legendHeight = legendElem.attr("height");
|
||||
|
||||
var rangeStep = 1;
|
||||
@@ -27,8 +27,9 @@ System.register(['angular', 'lodash', 'jquery', 'd3', './libs/d3-scale-chromatic
|
||||
|
||||
var colorScale = getColorScale(colorScheme, maxValue, minValue);
|
||||
legend.selectAll(".status-heatmap-color-legend-rect").data(valuesRange).enter().append("rect").attr("x", function (d) {
|
||||
return d * widthFactor;
|
||||
}).attr("y", 0).attr("width", rangeStep * widthFactor + 1) // Overlap rectangles to prevent gaps
|
||||
return d * widthFactor + 10;
|
||||
}) // shift all color rectangles to the right
|
||||
.attr("y", 0).attr("width", rangeStep * widthFactor + 1) // Overlap rectangles to prevent gaps
|
||||
.attr("height", legendHeight).attr("stroke-width", 0).attr("fill", function (d) {
|
||||
return colorScale(d);
|
||||
});
|
||||
@@ -41,7 +42,7 @@ System.register(['angular', 'lodash', 'jquery', 'd3', './libs/d3-scale-chromatic
|
||||
var legend = d3.select(legendElem.get(0));
|
||||
clearLegend(elem);
|
||||
|
||||
var legendWidth = Math.floor(legendElem.outerWidth()) - 30;
|
||||
var legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values
|
||||
var legendHeight = legendElem.attr("height");
|
||||
|
||||
var rangeStep = 10;
|
||||
@@ -55,8 +56,9 @@ System.register(['angular', 'lodash', 'jquery', 'd3', './libs/d3-scale-chromatic
|
||||
|
||||
var opacityScale = getOpacityScale(options, maxValue, minValue);
|
||||
legend.selectAll(".status-heatmap-opacity-legend-rect").data(valuesRange).enter().append("rect").attr("x", function (d) {
|
||||
return d * widthFactor;
|
||||
}).attr("y", 0).attr("width", rangeStep * widthFactor).attr("height", legendHeight).attr("stroke-width", 0).attr("fill", options.cardColor).style("opacity", function (d) {
|
||||
return d * widthFactor + 10;
|
||||
}) // shift all opacity rectangles to the right
|
||||
.attr("y", 0).attr("width", rangeStep * widthFactor).attr("height", legendHeight).attr("stroke-width", 0).attr("fill", options.cardColor).style("opacity", function (d) {
|
||||
return opacityScale(d);
|
||||
});
|
||||
|
||||
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAGA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAEjB,uDAAyB;IACzB,gBAAgB,EAAE,KAAK;IACvB,OAAO,EAAE,GAAG;;AAId,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAGhB,sCAAK;IACH,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,IAAI;EAGjB,sCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,OAAO;EAKnB,yBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,8BAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,uBAAwB;EACtB,WAAW,EAAE,MAAM;EACnB,SAAS,EAzCI,IAAI;EA0CjB,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,OAAO;;AAGhB,8BAA+B;EAC7B,IAAI,EAAE,OAAO;;AAIb,8BAAK;EACH,MAAM,EAAE,OAAe;EACvB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAGlC,8BAA+B;EAE7B,MAAM,EAAE,MAAM;EAGd,kCAAI;IAGF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,IAAI;EAGjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,OAAO;EAGjB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,OAAO",
|
||||
"sources": ["../../src/css/status-heatmap.scss"],
|
||||
"names": [],
|
||||
"file": "status-heatmap.css"
|
||||
}
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
.status-heatmap-canvas-wrapper {
|
||||
cursor: crosshair; }
|
||||
.status-heatmap-canvas-wrapper .datapoints-warning span {
|
||||
background-color: #333333;
|
||||
color: #d8d9da;
|
||||
padding: 1px; }
|
||||
|
||||
.status-heatmap-panel {
|
||||
position: relative; }
|
||||
.status-heatmap-panel .axis .tick text {
|
||||
fill: #d8d9da;
|
||||
color: #d8d9da;
|
||||
font-size: 11px; }
|
||||
.status-heatmap-panel .axis .tick line {
|
||||
opacity: 0.4;
|
||||
stroke: #8e8e8e; }
|
||||
.status-heatmap-panel svg {
|
||||
pointer-events: none; }
|
||||
.status-heatmap-panel svg rect {
|
||||
pointer-events: visiblePainted; }
|
||||
|
||||
.statusmap-tooltip {
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
background-color: #141414;
|
||||
color: #d8d9da; }
|
||||
.statusmap-tooltip .discrete-item {
|
||||
color: #52545c;
|
||||
padding: 1px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF; }
|
||||
|
||||
.statusmap-histogram rect {
|
||||
fill: #8e8e8e; }
|
||||
|
||||
.status-heatmap-crosshair line {
|
||||
stroke: #9f3023;
|
||||
stroke-width: 1; }
|
||||
|
||||
.status-heatmap-selection {
|
||||
stroke-width: 1;
|
||||
fill: rgba(102, 102, 102, 0.4);
|
||||
stroke: rgba(102, 102, 102, 0.8); }
|
||||
|
||||
.status-heatmap-legend-wrapper {
|
||||
margin: 0 10px; }
|
||||
.status-heatmap-legend-wrapper svg {
|
||||
height: 24px;
|
||||
float: left;
|
||||
white-space: nowrap; }
|
||||
.status-heatmap-legend-wrapper .status-heatmap-color-legend {
|
||||
margin-top: 4px; }
|
||||
.status-heatmap-legend-wrapper .status-heatmap-legend-values {
|
||||
display: inline-block; }
|
||||
.status-heatmap-legend-wrapper .axis .tick text {
|
||||
fill: #d8d9da;
|
||||
color: #d8d9da;
|
||||
font-size: 11px; }
|
||||
.status-heatmap-legend-wrapper .axis .tick line {
|
||||
opacity: 0.4;
|
||||
stroke: #8e8e8e; }
|
||||
.status-heatmap-legend-wrapper .axis .tick .domain {
|
||||
opacity: 0.4;
|
||||
stroke: #8e8e8e; }
|
||||
|
||||
/*# sourceMappingURL=statusmap.dark.css.map */
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAEjB,uDAAyB;IACzB,gBAAgB,ECDL,OAAO;IDElB,KAAK,ECLM,OAAO;IDMlB,OAAO,EAAE,GAAG;;AAId,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAGhB,sCAAK;IACH,IAAI,ECfG,OAAO;IDgBd,KAAK,EChBE,OAAO;IDiBd,SAAS,EEjBE,IAAI;EFoBjB,sCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECrBM,OAAO;ED0BvB,yBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,8BAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EACjB,WAAW,EAAE,MAAM;EACnB,SAAS,EEvCI,IAAI;EFwCjB,gBAAgB,ECrCC,OAAO;EDsCxB,KAAK,ECxCM,OAAO;ED0ClB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,8CAA8C;;AAI/D,yBAA0B;EACxB,IAAI,EClDY,OAAO;;ADsDvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAIlC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,ECxFG,OAAO;IDyFd,KAAK,ECzFE,OAAO;ID0Fd,SAAS,EE1FE,IAAI;EF6FjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC9FM,OAAO;EDiGrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECnGM,OAAO",
|
||||
"sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.dark.scss","../../src/css/_variables.scss"],
|
||||
"names": [],
|
||||
"file": "statusmap.dark.css"
|
||||
}
|
||||
+11
-5
@@ -1,7 +1,8 @@
|
||||
.status-heatmap-canvas-wrapper {
|
||||
cursor: crosshair; }
|
||||
.status-heatmap-canvas-wrapper .datapoints-warning span {
|
||||
background-color: white;
|
||||
background-color: #e9edf2;
|
||||
color: #52545c;
|
||||
padding: 1px; }
|
||||
|
||||
.status-heatmap-panel {
|
||||
@@ -18,17 +19,22 @@
|
||||
.status-heatmap-panel svg rect {
|
||||
pointer-events: visiblePainted; }
|
||||
|
||||
.status-heatmap-tooltip {
|
||||
.statusmap-tooltip {
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
background-color: #dde4ed;
|
||||
color: #52545c; }
|
||||
.statusmap-tooltip .discrete-item {
|
||||
color: #52545c;
|
||||
padding: 1px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF; }
|
||||
|
||||
.status-heatmap-histogram rect {
|
||||
.statusmap-histogram rect {
|
||||
fill: #767980; }
|
||||
|
||||
.status-heatmap-crosshair line {
|
||||
stroke: #b30000;
|
||||
stroke: #9e2f22;
|
||||
stroke-width: 1; }
|
||||
|
||||
.status-heatmap-selection {
|
||||
@@ -57,4 +63,4 @@
|
||||
opacity: 0.4;
|
||||
stroke: #767980; }
|
||||
|
||||
/*# sourceMappingURL=status-heatmap.css.map */
|
||||
/*# sourceMappingURL=statusmap.light.css.map */
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAEjB,uDAAyB;IACzB,gBAAgB,ECDL,OAAO;IDElB,KAAK,ECLM,OAAO;IDMlB,OAAO,EAAE,GAAG;;AAId,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAGhB,sCAAK;IACH,IAAI,ECfG,OAAO;IDgBd,KAAK,EChBE,OAAO;IDiBd,SAAS,EEjBE,IAAI;EFoBjB,sCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECrBM,OAAO;ED0BvB,yBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,8BAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EACjB,WAAW,EAAE,MAAM;EACnB,SAAS,EEvCI,IAAI;EFwCjB,gBAAgB,ECrCC,OAAO;EDsCxB,KAAK,ECxCM,OAAO;ED0ClB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,8CAA8C;;AAI/D,yBAA0B;EACxB,IAAI,EClDY,OAAO;;ADsDvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAIlC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,ECxFG,OAAO;IDyFd,KAAK,ECzFE,OAAO;ID0Fd,SAAS,EE1FE,IAAI;EF6FjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC9FM,OAAO;EDiGrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECnGM,OAAO",
|
||||
"sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.light.scss","../../src/css/_variables.scss"],
|
||||
"names": [],
|
||||
"file": "statusmap.light.css"
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Vendored
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 64 KiB |
Vendored
+11
-3
@@ -1,14 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['./color_legend', './status_heatmap_ctrl'], function (_export, _context) {
|
||||
System.register(['app/plugins/sdk', './status_heatmap_ctrl'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var StatusHeatmapCtrl;
|
||||
var loadPluginCss, StatusHeatmapCtrl;
|
||||
return {
|
||||
setters: [function (_color_legend) {}, function (_status_heatmap_ctrl) {
|
||||
setters: [function (_appPluginsSdk) {
|
||||
loadPluginCss = _appPluginsSdk.loadPluginCss;
|
||||
}, function (_status_heatmap_ctrl) {
|
||||
StatusHeatmapCtrl = _status_heatmap_ctrl.StatusHeatmapCtrl;
|
||||
}],
|
||||
execute: function () {
|
||||
|
||||
loadPluginCss({
|
||||
dark: 'plugins/flant-statusmap-panel/css/statusmap.dark.css',
|
||||
light: 'plugins/flant-statusmap-panel/css/statusmap.light.css'
|
||||
});
|
||||
|
||||
_export('PanelCtrl', StatusHeatmapCtrl);
|
||||
}
|
||||
};
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/module.js"],"names":["loadPluginCss","StatusHeatmapCtrl","dark","light"],"mappings":";;;;;;;;AAAQA,mB,kBAAAA,a;;AACCC,uB,wBAAAA,iB;;;;AAETD,oBAAc;AACZE,cAAM,sDADM;AAEZC,eAAO;AAFK,OAAd;;2BAMEF,iB","file":"module.js","sourcesContent":["import {loadPluginCss} from 'app/plugins/sdk';\nimport { StatusHeatmapCtrl } from './status_heatmap_ctrl';\n\nloadPluginCss({\n dark: 'plugins/flant-statusmap-panel/css/statusmap.dark.css',\n light: 'plugins/flant-statusmap-panel/css/statusmap.light.css'\n});\n\nexport {\n StatusHeatmapCtrl as PanelCtrl\n};\n"]}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/options_editor.js"],"names":["statusHeatmapOptionsEditor","restrict","scope","templateUrl","controller","StatusHeatmapOptionsEditorCtrl","kbn","$scope","editor","panelCtrl","ctrl","panel","unitFormats","getUnitFormats","render","subItem","data","unitFormat","value"],"mappings":";;;;;;;;;;;;;AAkBO,WAASA,0BAAT,GAAsC;AAC3C;;AACA,WAAO;AACLC,gBAAU,GADL;AAELC,aAAO,IAFF;AAGLC,mBAAa,mEAHR;AAILC,kBAAYC;AAJP,KAAP;AAMD;;wCAReL,0B;;;;AAlBTM,S;;;;;;;;;;;;;;;;;;;;;gDAEMD,8B;AACX,gDAAYE,MAAZ,EAAoB;AAAA;;AAClBA,iBAAOC,MAAP,GAAgB,IAAhB;AACA,eAAKC,SAAL,GAAiBF,OAAOG,IAAxB;AACA,eAAKC,KAAL,GAAa,KAAKF,SAAL,CAAeE,KAA5B;AACA,eAAKC,WAAL,GAAmBN,IAAIO,cAAJ,EAAnB;;AAEA,eAAKJ,SAAL,CAAeK,MAAf;AACD;;;;wCAEaC,O,EAAS;AACrB,iBAAKJ,KAAL,CAAWK,IAAX,CAAgBC,UAAhB,GAA6BF,QAAQG,KAArC;AACA,iBAAKT,SAAL,CAAeK,MAAf;AACD","file":"options_editor.js","sourcesContent":["import kbn from 'app/core/utils/kbn';\n\nexport class StatusHeatmapOptionsEditorCtrl {\n constructor($scope) {\n $scope.editor = this;\n this.panelCtrl = $scope.ctrl;\n this.panel = this.panelCtrl.panel;\n this.unitFormats = kbn.getUnitFormats();\n\n this.panelCtrl.render();\n }\n\n setUnitFormat(subItem) {\n this.panel.data.unitFormat = subItem.value;\n this.panelCtrl.render();\n }\n}\n\nexport function statusHeatmapOptionsEditor() {\n 'use strict';\n return {\n restrict: 'E',\n scope: true,\n templateUrl: 'public/plugins/flant-statusmap-panel/partials/options_editor.html',\n controller: StatusHeatmapOptionsEditorCtrl,\n };\n}\n"]}
|
||||
Vendored
+4
-3
@@ -20,12 +20,13 @@
|
||||
|
||||
],
|
||||
"screenshots": [
|
||||
{"name": "Panel", "path": "img/flant-statusmap-panel.png"},
|
||||
{"name": "Panel with light theme", "path": "img/flant-statusmap-panel.png"},
|
||||
{"name": "Panel with dark theme", "path": "img/flant-statusmap-panel-dark.png"},
|
||||
{"name": "Color mapping", "path": "img/color-mapping.png"},
|
||||
{"name": "Queries example", "path": "img/queries-example.png"}
|
||||
],
|
||||
"version": "0.0.1",
|
||||
"updated": "2018-09-17"
|
||||
"version": "0.0.2",
|
||||
"updated": "2018-10-17"
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+6
-4
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/kbn', './rendering', './options_editor', './color_mode_discrete', './css/status-heatmap.css!'], function (_export, _context) {
|
||||
System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/kbn', './color_legend', './rendering', './options_editor', './color_mode_discrete'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var MetricsPanelCtrl, _, contextSrv, kbn, rendering, statusHeatmapOptionsEditor, ColorModeDiscrete, CANVAS, SVG, VALUE_INDEX, TIME_INDEX, panelDefaults, renderer, colorSchemes, colorModes, opacityScales, StatusHeatmapCtrl;
|
||||
@@ -44,13 +44,13 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k
|
||||
contextSrv = _appCoreCore.contextSrv;
|
||||
}, function (_appCoreUtilsKbn) {
|
||||
kbn = _appCoreUtilsKbn.default;
|
||||
}, function (_rendering) {
|
||||
}, function (_color_legend) {}, function (_rendering) {
|
||||
rendering = _rendering.default;
|
||||
}, function (_options_editor) {
|
||||
statusHeatmapOptionsEditor = _options_editor.statusHeatmapOptionsEditor;
|
||||
}, function (_color_mode_discrete) {
|
||||
ColorModeDiscrete = _color_mode_discrete.ColorModeDiscrete;
|
||||
}, function (_cssStatusHeatmapCss) {}],
|
||||
}],
|
||||
execute: function () {
|
||||
CANVAS = 'CANVAS';
|
||||
SVG = 'SVG';
|
||||
@@ -109,7 +109,7 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k
|
||||
{ name: 'Blues', value: 'interpolateBlues', invert: 'dark' }, { name: 'Greens', value: 'interpolateGreens', invert: 'dark' }, { name: 'Greys', value: 'interpolateGreys', invert: 'dark' }, { name: 'Oranges', value: 'interpolateOranges', invert: 'dark' }, { name: 'Purples', value: 'interpolatePurples', invert: 'dark' }, { name: 'Reds', value: 'interpolateReds', invert: 'dark' },
|
||||
|
||||
// Sequential (Multi-Hue)
|
||||
{ name: 'BuGn', value: 'interpolateBuGn', invert: 'dark' }, { name: 'BuPu', value: 'interpolateBuPu', invert: 'dark' }, { name: 'GnBu', value: 'interpolateGnBu', invert: 'dark' }, { name: 'OrRd', value: 'interpolateOrRd', invert: 'dark' }, { name: 'PuBuGn', value: 'interpolatePuBuGn', invert: 'dark' }, { name: 'PuBu', value: 'interpolatePuBu', invert: 'dark' }, { name: 'PuRd', value: 'interpolatePuRd', invert: 'dark' }, { name: 'RdPu', value: 'interpolateRdPu', invert: 'dark' }, { name: 'YlGnBu', value: 'interpolateYlGnBu', invert: 'dark' }, { name: 'YlGn', value: 'interpolateYlGn', invert: 'dark' }, { name: 'YlOrBr', value: 'interpolateYlOrBr', invert: 'dark' }, { name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'darm' }];
|
||||
{ name: 'BuGn', value: 'interpolateBuGn', invert: 'dark' }, { name: 'BuPu', value: 'interpolateBuPu', invert: 'dark' }, { name: 'GnBu', value: 'interpolateGnBu', invert: 'dark' }, { name: 'OrRd', value: 'interpolateOrRd', invert: 'dark' }, { name: 'PuBuGn', value: 'interpolatePuBuGn', invert: 'dark' }, { name: 'PuBu', value: 'interpolatePuBu', invert: 'dark' }, { name: 'PuRd', value: 'interpolatePuRd', invert: 'dark' }, { name: 'RdPu', value: 'interpolateRdPu', invert: 'dark' }, { name: 'YlGnBu', value: 'interpolateYlGnBu', invert: 'dark' }, { name: 'YlGn', value: 'interpolateYlGn', invert: 'dark' }, { name: 'YlOrBr', value: 'interpolateYlOrBr', invert: 'dark' }, { name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'dark' }];
|
||||
colorModes = ['opacity', 'spectrum', 'discrete'];
|
||||
opacityScales = ['linear', 'sqrt'];
|
||||
|
||||
@@ -123,6 +123,7 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k
|
||||
|
||||
_this.onRenderComplete = function (data) {
|
||||
_this.graph.chartWidth = data.chartWidth;
|
||||
_this.renderingCompleted();
|
||||
};
|
||||
|
||||
_this.calculateInterval = function () {
|
||||
@@ -344,6 +345,7 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k
|
||||
_this.events.on('init-edit-mode', _this.onInitEditMode);
|
||||
_this.events.on('render', _this.onRender);
|
||||
_this.events.on('refresh', _this.postRefresh);
|
||||
// custom event from rendering.js
|
||||
_this.events.on('render-complete', _this.onRenderComplete);
|
||||
return _this;
|
||||
}
|
||||
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+3
-3
@@ -88,7 +88,7 @@ System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_exp
|
||||
}, {
|
||||
key: 'add',
|
||||
value: function add() {
|
||||
this.tooltip = d3.select("body").append("div").attr("class", "heatmap-tooltip graph-tooltip grafana-tooltip");
|
||||
this.tooltip = d3.select("body").append("div").attr("class", "statusmap-tooltip graph-tooltip grafana-tooltip");
|
||||
}
|
||||
}, {
|
||||
key: 'destroy',
|
||||
@@ -128,7 +128,7 @@ System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_exp
|
||||
var tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
var time = this.dashboard.formatDate(+x, tooltipTimeFormat);
|
||||
|
||||
var tooltipHtml = '<div class="graph-tooltip-time">' + time + '</div>\n <div class="status-heatmap-histogram"></div>';
|
||||
var tooltipHtml = '<div class="graph-tooltip-time">' + time + '</div>\n <div class="statusmap-histogram"></div>';
|
||||
|
||||
if (this.panel.color.mode === 'discrete') {
|
||||
var statuses = this.panelCtrl.discreteHelper.convertValuesToTooltips(values);
|
||||
@@ -139,7 +139,7 @@ System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_exp
|
||||
statusesHtml = "statuses:";
|
||||
}
|
||||
tooltipHtml += '\n <div>\n name: <b>' + y + '</b> <br>\n ' + statusesHtml + '\n <ul>\n ' + _.join(_.map(statuses, function (v) {
|
||||
return '<li style="background-color: ' + v.color + '; padding: 1px; font-weight: bold; text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF">' + v.tooltip + '</li>';
|
||||
return '<li style="background-color: ' + v.color + '" class="discrete-item">' + v.tooltip + '</li>';
|
||||
}), "") + '\n </ul>\n </div>';
|
||||
} else {
|
||||
if (values.length === 1) {
|
||||
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
+4
-4
@@ -89,7 +89,7 @@ function drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minVal
|
||||
let legend = d3.select(legendElem.get(0));
|
||||
clearLegend(elem);
|
||||
|
||||
let legendWidth = Math.floor(legendElem.outerWidth()) - 30;
|
||||
let legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values
|
||||
let legendHeight = legendElem.attr("height");
|
||||
|
||||
let rangeStep = 1;
|
||||
@@ -108,7 +108,7 @@ function drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minVal
|
||||
legend.selectAll(".status-heatmap-color-legend-rect")
|
||||
.data(valuesRange)
|
||||
.enter().append("rect")
|
||||
.attr("x", d => d * widthFactor)
|
||||
.attr("x", d => d * widthFactor + 10) // shift all color rectangles to the right
|
||||
.attr("y", 0)
|
||||
.attr("width", rangeStep * widthFactor + 1) // Overlap rectangles to prevent gaps
|
||||
.attr("height", legendHeight)
|
||||
@@ -123,7 +123,7 @@ function drawOpacityLegend(elem, options, rangeFrom, rangeTo, maxValue, minValue
|
||||
let legend = d3.select(legendElem.get(0));
|
||||
clearLegend(elem);
|
||||
|
||||
let legendWidth = Math.floor(legendElem.outerWidth()) - 30;
|
||||
let legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values
|
||||
let legendHeight = legendElem.attr("height");
|
||||
|
||||
let rangeStep = 10;
|
||||
@@ -139,7 +139,7 @@ function drawOpacityLegend(elem, options, rangeFrom, rangeTo, maxValue, minValue
|
||||
legend.selectAll(".status-heatmap-opacity-legend-rect")
|
||||
.data(valuesRange)
|
||||
.enter().append("rect")
|
||||
.attr("x", d => d * widthFactor)
|
||||
.attr("x", d => d * widthFactor + 10) // shift all opacity rectangles to the right
|
||||
.attr("y", 0)
|
||||
.attr("width", rangeStep * widthFactor)
|
||||
.attr("height", legendHeight)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
$font-size-sm: 12px !default;
|
||||
|
||||
|
||||
.status-heatmap-canvas-wrapper {
|
||||
// position: relative;
|
||||
cursor: crosshair;
|
||||
|
||||
.datapoints-warning span {
|
||||
background-color: white;
|
||||
background-color: $warning-bg;
|
||||
color: $text-color;
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
||||
@@ -16,14 +14,14 @@ $font-size-sm: 12px !default;
|
||||
|
||||
.axis .tick {
|
||||
text {
|
||||
fill: #52545c;
|
||||
color: #52545c;
|
||||
font-size: 11px;
|
||||
fill: $text-color;
|
||||
color: $text-color;
|
||||
font-size: $font-size-tick;
|
||||
}
|
||||
|
||||
line {
|
||||
opacity: 0.4;
|
||||
stroke: #767980;
|
||||
stroke: $text-color-weak;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,20 +35,27 @@ $font-size-sm: 12px !default;
|
||||
}
|
||||
}
|
||||
|
||||
.status-heatmap-tooltip {
|
||||
.statusmap-tooltip {
|
||||
white-space: nowrap;
|
||||
font-size: $font-size-sm;
|
||||
background-color: #dde4ed;
|
||||
color: #52545c;
|
||||
background-color: $graph-tooltip-bg;
|
||||
color: $text-color;
|
||||
|
||||
.discrete-item {
|
||||
color: #52545c;
|
||||
padding: 1px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.status-heatmap-histogram rect {
|
||||
fill: #767980;
|
||||
.statusmap-histogram rect {
|
||||
fill: $text-color-weak;
|
||||
}
|
||||
|
||||
.status-heatmap-crosshair {
|
||||
line {
|
||||
stroke: darken(red,15%);
|
||||
stroke: darken($red,15%);
|
||||
stroke-width: 1;
|
||||
}
|
||||
}
|
||||
@@ -61,14 +66,11 @@ $font-size-sm: 12px !default;
|
||||
stroke: rgba(102, 102, 102, 0.8);
|
||||
}
|
||||
|
||||
|
||||
.status-heatmap-legend-wrapper {
|
||||
// @include clearfix();
|
||||
margin: 0 10px;
|
||||
//padding-top: 10px;
|
||||
|
||||
svg {
|
||||
//width: 100%;
|
||||
//max-width: 1300px;
|
||||
height: 24px;
|
||||
float: left;
|
||||
white-space: nowrap;
|
||||
@@ -85,19 +87,19 @@ $font-size-sm: 12px !default;
|
||||
|
||||
.axis .tick {
|
||||
text {
|
||||
fill: #52545c;
|
||||
color: #52545c;
|
||||
font-size: 11px;
|
||||
fill: $text-color;
|
||||
color: $text-color;
|
||||
font-size: $font-size-tick;
|
||||
}
|
||||
|
||||
line {
|
||||
opacity: 0.4;
|
||||
stroke: #767980;
|
||||
stroke: $text-color-weak;
|
||||
}
|
||||
|
||||
.domain {
|
||||
opacity: 0.4;
|
||||
stroke: #767980;
|
||||
stroke: $text-color-weak;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Dark variables
|
||||
$text-color: #d8d9da; // $gray-4
|
||||
$text-color-weak: #8e8e8e; // $gray-2
|
||||
$graph-tooltip-bg: #141414; // $dark-1
|
||||
$warning-bg: #333333; // $dark-4
|
||||
|
||||
$theme-name: dark;
|
||||
$white: #fff;
|
||||
$red: #d44a3a;
|
||||
@@ -0,0 +1,10 @@
|
||||
// Light variables
|
||||
$text-color: #52545c; // $gray-1
|
||||
$text-color-weak: #767980; // $gray-2
|
||||
$graph-tooltip-bg: #dde4ed; // $gray-5
|
||||
$warning-bg: #e9edf2; // $gray-6
|
||||
|
||||
$theme-name: light;
|
||||
$white: #fff;
|
||||
$red: #d44939;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
$font-size-sm: 12px !default;
|
||||
$font-size-tick: 11px;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
@import "variables";
|
||||
@import "variables.dark";
|
||||
@import "statusmap"
|
||||
@@ -0,0 +1,3 @@
|
||||
@import "variables";
|
||||
@import "variables.light";
|
||||
@import "statusmap"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
+6
-1
@@ -1,6 +1,11 @@
|
||||
import './color_legend';
|
||||
import {loadPluginCss} from 'app/plugins/sdk';
|
||||
import { StatusHeatmapCtrl } from './status_heatmap_ctrl';
|
||||
|
||||
loadPluginCss({
|
||||
dark: 'plugins/flant-statusmap-panel/css/statusmap.dark.css',
|
||||
light: 'plugins/flant-statusmap-panel/css/statusmap.light.css'
|
||||
});
|
||||
|
||||
export {
|
||||
StatusHeatmapCtrl as PanelCtrl
|
||||
};
|
||||
|
||||
+4
-3
@@ -20,12 +20,13 @@
|
||||
|
||||
],
|
||||
"screenshots": [
|
||||
{"name": "Panel", "path": "img/flant-statusmap-panel.png"},
|
||||
{"name": "Panel with light theme", "path": "img/flant-statusmap-panel.png"},
|
||||
{"name": "Panel with dark theme", "path": "img/flant-statusmap-panel-dark.png"},
|
||||
{"name": "Color mapping", "path": "img/color-mapping.png"},
|
||||
{"name": "Queries example", "path": "img/queries-example.png"}
|
||||
],
|
||||
"version": "0.0.1",
|
||||
"updated": "2018-09-17"
|
||||
"version": "0.0.2",
|
||||
"updated": "2018-10-17"
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
|
||||
@@ -3,13 +3,13 @@ import _ from 'lodash';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
|
||||
import './color_legend';
|
||||
import rendering from './rendering';
|
||||
// import aggregates, { aggregatesMap } from './aggregates';
|
||||
// import fragments, { fragmentsMap } from './fragments';
|
||||
// import { labelFormats } from './xAxisLabelFormats';
|
||||
import {statusHeatmapOptionsEditor} from './options_editor';
|
||||
import {ColorModeDiscrete} from "./color_mode_discrete";
|
||||
import './css/status-heatmap.css!';
|
||||
|
||||
const CANVAS = 'CANVAS';
|
||||
const SVG = 'SVG';
|
||||
@@ -89,7 +89,7 @@ const colorSchemes = [
|
||||
{ name: 'YlGnBu', value: 'interpolateYlGnBu', invert: 'dark' },
|
||||
{ name: 'YlGn', value: 'interpolateYlGn', invert: 'dark' },
|
||||
{ name: 'YlOrBr', value: 'interpolateYlOrBr', invert: 'dark' },
|
||||
{ name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'darm' }
|
||||
{ name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'dark' }
|
||||
];
|
||||
|
||||
let colorModes = ['opacity', 'spectrum', 'discrete'];
|
||||
@@ -133,11 +133,13 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl {
|
||||
this.events.on('init-edit-mode', this.onInitEditMode);
|
||||
this.events.on('render', this.onRender);
|
||||
this.events.on('refresh', this.postRefresh);
|
||||
// custom event from rendering.js
|
||||
this.events.on('render-complete', this.onRenderComplete);
|
||||
}
|
||||
|
||||
onRenderComplete = (data) => {
|
||||
this.graph.chartWidth = data.chartWidth;
|
||||
this.renderingCompleted();
|
||||
};
|
||||
|
||||
// override calculateInterval for discrete color mode
|
||||
|
||||
+3
-3
@@ -42,7 +42,7 @@ export class StatusHeatmapTooltip {
|
||||
add() {
|
||||
this.tooltip = d3.select("body")
|
||||
.append("div")
|
||||
.attr("class", "heatmap-tooltip graph-tooltip grafana-tooltip");
|
||||
.attr("class", "statusmap-tooltip graph-tooltip grafana-tooltip");
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@@ -79,7 +79,7 @@ export class StatusHeatmapTooltip {
|
||||
let time = this.dashboard.formatDate(+x, tooltipTimeFormat);
|
||||
|
||||
let tooltipHtml = `<div class="graph-tooltip-time">${time}</div>
|
||||
<div class="status-heatmap-histogram"></div>`;
|
||||
<div class="statusmap-histogram"></div>`;
|
||||
|
||||
if (this.panel.color.mode === 'discrete') {
|
||||
let statuses = this.panelCtrl.discreteHelper.convertValuesToTooltips(values);
|
||||
@@ -94,7 +94,7 @@ export class StatusHeatmapTooltip {
|
||||
name: <b>${y}</b> <br>
|
||||
${statusesHtml}
|
||||
<ul>
|
||||
${_.join(_.map(statuses, v => `<li style="background-color: ${v.color}; padding: 1px; font-weight: bold; text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF">${v.tooltip}</li>`), "")}
|
||||
${_.join(_.map(statuses, v => `<li style="background-color: ${v.color}" class="discrete-item">${v.tooltip}</li>`), "")}
|
||||
</ul>
|
||||
</div>`;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user