web/gui: Added support for per series styling for dygraphs (#8668)
dpsy4 committed
Jan 4, 2021 at 07:10 UTC
b79b67b043cee4994e89a86e646fed9284b72cff
3 files changed
+112
-5
CONTRIBUTORS.md
+2
-1
@@ -28,7 +28,7 @@ The Contributor (_you_) hereby assigns Netdata Inc. copyright in his
28
contributions, to be licensed under the same terms as the rest of the code.
29
30
> _Note: this means we may re-license Netdata (your contributions included)
31
-> any way we see fit, without asking your permission.
31
+> any way we see fit, without asking your permission.
32
> We intend to keep the Netdata agent forever FOSS.
33
> But open-source licenses have significant differences and in our attempt to
34
> help Netdata grow we may have to distribute it under a different license.
@@ -130,6 +130,7 @@ This is the list of contributors that have signed this agreement:
130
|@akwan|Alan Kwan||
131
|@underhood|Timotej Šiškovič||
132
|@stevenh|Steven Hartland|steven.hartland@multiplay.co.uk|
133
+|@dpsy4|Dave Sitek||
134
|@devinrsmith|Devin Smith||
135
136
[](<>)
web/gui/dashboard.js
+55
-2
@@ -2199,6 +2199,9 @@ NETDATA.dygraphChartCreate = function (state, data) {
2199
visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names),
2200
logscale: NETDATA.chartLibraries.dygraph.isLogScale(state) ? 'y' : undefined,
2201
2202
+ // Expects a string in the format "<series name>: <style>" where each series is separated by a |
2203
+ perSeriesStyle: NETDATA.dataAttribute(state.element, 'dygraph-per-series-style', ''),
2204
+
2205
axes: {
2206
x: {
2207
pixelsPerLabel: NETDATA.dataAttribute(state.element, 'dygraph-xpixelsperlabel', 50),
@@ -2855,9 +2858,14 @@ NETDATA.dygraphChartCreate = function (state, data) {
2858
//state.tmp.dygraph_options.isZoomedIgnoreProgrammaticZoom = true;
2859
}
2860
2858
- state.tmp.dygraph_instance = new Dygraph(state.element_chart,
2859
- data.result.data, state.tmp.dygraph_options);
2861
+ let seriesStyles = NETDATA.dygraphGetSeriesStyle(state.tmp.dygraph_options);
2862
+ state.tmp.dygraph_options.series = seriesStyles;
2863
2864
+ state.tmp.dygraph_instance = new Dygraph(
2865
+ state.element_chart,
2866
+ data.result.data,
2867
+ state.tmp.dygraph_options
2868
+ );
2869
2870
state.tmp.dygraph_history_tip_element = document.createElement('div');
2871
state.tmp.dygraph_history_tip_element.innerHTML = `
@@ -2895,6 +2903,51 @@ NETDATA.dygraphChartCreate = function (state, data) {
2903
2904
return true;
2905
};
2906
+
2907
+NETDATA.dygraphGetSeriesStyle = function(dygraphOptions) {
2908
+ const seriesStyleStr = dygraphOptions.perSeriesStyle;
2909
+ let formattedStyles = {};
2910
+
2911
+ if (seriesStyleStr === '') {
2912
+ return formattedStyles;
2913
+ }
2914
+
2915
+ // Parse the config string into a JSON object
2916
+ let styles = seriesStyleStr.replace(' ', '').split('|');
2917
+
2918
+ styles.forEach(style => {
2919
+ const keys = style.split(':');
2920
+ formattedStyles[keys[0]] = keys[1];
2921
+ });
2922
+
2923
+ for (let key in formattedStyles) {
2924
+ if (formattedStyles.hasOwnProperty(key)) {
2925
+ let settings;
2926
+
2927
+ switch (formattedStyles[key]) {
2928
+ case 'line':
2929
+ settings = { fillGraph: false };
2930
+ break;
2931
+ case 'area':
2932
+ settings = { fillGraph: true };
2933
+ break;
2934
+ case 'dot':
2935
+ settings = {
2936
+ fillGraph: false,
2937
+ drawPoints: true,
2938
+ pointSize: dygraphOptions.pointSize
2939
+ };
2940
+ break;
2941
+ default:
2942
+ settings = undefined;
2943
+ }
2944
+
2945
+ formattedStyles[key] = settings;
2946
+ }
2947
+ }
2948
+
2949
+ return formattedStyles;
2950
+};
2951
// ----------------------------------------------------------------------------------------------------------------
2952
// sparkline
2953
web/gui/src/dashboard.js/charting/dygraph.js
+55
-2
@@ -314,6 +314,9 @@ NETDATA.dygraphChartCreate = function (state, data) {
314
visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names),
315
logscale: NETDATA.chartLibraries.dygraph.isLogScale(state) ? 'y' : undefined,
316
317
+ // Expects a string in the format "<series name>: <style>" where each series is separated by a |
318
+ perSeriesStyle: NETDATA.dataAttribute(state.element, 'dygraph-per-series-style', ''),
319
+
320
axes: {
321
x: {
322
pixelsPerLabel: NETDATA.dataAttribute(state.element, 'dygraph-xpixelsperlabel', 50),
@@ -970,9 +973,14 @@ NETDATA.dygraphChartCreate = function (state, data) {
973
//state.tmp.dygraph_options.isZoomedIgnoreProgrammaticZoom = true;
974
}
975
973
- state.tmp.dygraph_instance = new Dygraph(state.element_chart,
974
- data.result.data, state.tmp.dygraph_options);
976
+ let seriesStyles = NETDATA.dygraphGetSeriesStyle(state.tmp.dygraph_options);
977
+ state.tmp.dygraph_options.series = seriesStyles;
978
979
+ state.tmp.dygraph_instance = new Dygraph(
980
+ state.element_chart,
981
+ data.result.data,
982
+ state.tmp.dygraph_options
983
+ );
984
985
state.tmp.dygraph_history_tip_element = document.createElement('div');
986
state.tmp.dygraph_history_tip_element.innerHTML = `
@@ -1010,3 +1018,48 @@ NETDATA.dygraphChartCreate = function (state, data) {
1018
1019
return true;
1020
};
1021
+
1022
+NETDATA.dygraphGetSeriesStyle = function(dygraphOptions) {
1023
+ const seriesStyleStr = dygraphOptions.perSeriesStyle;
1024
+ let formattedStyles = {};
1025
+
1026
+ if (seriesStyleStr === '') {
1027
+ return formattedStyles;
1028
+ }
1029
+
1030
+ // Parse the config string into a JSON object
1031
+ let styles = seriesStyleStr.replace(' ', '').split('|');
1032
+
1033
+ styles.forEach(style => {
1034
+ const keys = style.split(':');
1035
+ formattedStyles[keys[0]] = keys[1];
1036
+ });
1037
+
1038
+ for (let key in formattedStyles) {
1039
+ if (formattedStyles.hasOwnProperty(key)) {
1040
+ let settings;
1041
+
1042
+ switch (formattedStyles[key]) {
1043
+ case 'line':
1044
+ settings = { fillGraph: false };
1045
+ break;
1046
+ case 'area':
1047
+ settings = { fillGraph: true };
1048
+ break;
1049
+ case 'dot':
1050
+ settings = {
1051
+ fillGraph: false,
1052
+ drawPoints: true,
1053
+ pointSize: dygraphOptions.pointSize
1054
+ };
1055
+ break;
1056
+ default:
1057
+ settings = undefined;
1058
+ }
1059
+
1060
+ formattedStyles[key] = settings;
1061
+ }
1062
+ }
1063
+
1064
+ return formattedStyles;
1065
+};