@cryptotaxi247 / netdata-1 / commits / b1b1bedac

#3925 implementation (#6903)

* issue #3925 implement optional fixed size badges * add docu related to #3925 * explicit cast (thiagoftsm) an split to multiline * implement clipping of text when fixed_width_label enabled * Update web/api/badges/README.md improved docu based on suggestion from @joelhans Co-Authored-By: Joel Hans <joel.g.hans@gmail.com> * update docu per req. of @thiagoftsm

Timo committed Sep 29, 2019 at 14:39 UTC b1b1bedacb3187b61d47c72322688d56f37904f2
3 files changed +82 -30
web/api/badges/README.md
+8
@@ -214,6 +214,14 @@ These are options dedicated to badges:
214 <img src="https://registry.my-netdata.io/api/v1/badge.svg?chart=system.cpu&after=-60&scale=175"></img> `scale=175`<br/>
215 <img src="https://registry.my-netdata.io/api/v1/badge.svg?chart=system.cpu&after=-60&scale=200"></img> `scale=200`
216
217 +- `fixed_width_lbl=NUMBER` and `fixed_width_val=NUMBER`
218 +
219 + This parameter overrides auto-sizing of badges and displays them at fixed widths. `fixed_width_lbl` determines the size of the label's left side (label/name). `fixed_width_val` determines the size of the the label's right side (value). You must set both parameters together, or they will be ignored.
220 +
221 + You should set the label/value widths wide enough to provide space for all the possible values/contents of the badge you're requesting. In case the text cannot fit the space given it will be clipped.
222 +
223 + The `scale` parameter still applies on the values you give to `fixed_width_lbl` and `fixed_width_val`.
224 +
225 - `refresh=auto` or `refresh=SECONDS`
226
227 This option enables auto-refreshing of images. Netdata will send the HTTP header `Refresh: SECONDS` to the web browser, thus requesting automatic refresh of the images at regular intervals.
web/api/badges/web_buffer_svg.c
+73 -29
@@ -688,7 +688,7 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
688 // colors
689 #define COLOR_STRING_SIZE 100
690
691 -void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options) {
691 +void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options, int fixed_width_lbl, int fixed_width_val) {
692 char value_color_buffer[COLOR_STRING_SIZE + 1]
693 , value_string[VALUE_STRING_SIZE + 1]
694 , label_escaped[LABEL_STRING_SIZE + 1]
@@ -696,7 +696,8 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
696 , label_color_escaped[COLOR_STRING_SIZE + 1]
697 , value_color_escaped[COLOR_STRING_SIZE + 1];
698
699 - double label_width, value_width, total_width, height = 20.0, font_size = 11.0, text_offset = 5.8, round_corner = 3.0;
699 + double label_width = (double)fixed_width_lbl, value_width = (double)fixed_width_val, total_width;
700 + double height = 20.0, font_size = 11.0, text_offset = 5.8, round_corner = 3.0;
701
702 if(scale < 100) scale = 100;
703
@@ -709,8 +710,10 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
710 calc_colorz(value_color, value_color_buffer, COLOR_STRING_SIZE, value);
711 format_value_and_unit(value_string, VALUE_STRING_SIZE, (options & RRDR_OPTION_DISPLAY_ABS)?calculated_number_fabs(value):value, units, precision);
712
712 - label_width = verdana11_width(label, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
713 - value_width = verdana11_width(value_string, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
713 + if(fixed_width_lbl <= 0 || fixed_width_val <= 0) {
714 + label_width = verdana11_width(label, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
715 + value_width = verdana11_width(value_string, font_size) + (BADGE_HORIZONTAL_PADDING * 2);
716 + }
717 total_width = label_width + value_width;
718
719 escape_xmlz(label_escaped, label, LABEL_STRING_SIZE);
@@ -740,16 +743,49 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
743 "<rect class=\"bdge-ttl-width\" width=\"%0.2f\" height=\"%0.2f\" rx=\"%0.2f\" fill=\"#fff\"/>"
744 "</mask>"
745 "<g mask=\"url(#round)\">"
743 - "<rect class=\"bdge-rect-lbl\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>"
744 - "<rect class=\"bdge-rect-val\" x=\"%0.2f\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>"
746 + "<rect class=\"bdge-rect-lbl\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>",
747 + total_width, height,
748 + total_width, height, round_corner,
749 + label_width, height, label_color_escaped); //<rect class="bdge-rect-lbl"
750 +
751 + if(fixed_width_lbl > 0 && fixed_width_val > 0) {
752 + buffer_sprintf(wb,
753 + "<clipPath id=\"lbl-rect\">"
754 + "<rect class=\"bdge-rect-lbl\" width=\"%0.2f\" height=\"%0.2f\"/>"
755 + "</clipPath>",
756 + label_width, height); //<clipPath id="lbl-rect"> <rect class="bdge-rect-lbl"
757 + }
758 +
759 + buffer_sprintf(wb,
760 + "<rect class=\"bdge-rect-val\" x=\"%0.2f\" width=\"%0.2f\" height=\"%0.2f\" fill=\"%s\"/>",
761 + label_width, value_width, height, value_color_escaped);
762 +
763 + if(fixed_width_lbl > 0 && fixed_width_val > 0) {
764 + buffer_sprintf(wb,
765 + "<clipPath id=\"val-rect\">"
766 + "<rect class=\"bdge-rect-val\" x=\"%0.2f\" width=\"%0.2f\" height=\"%0.2f\"/>"
767 + "</clipPath>",
768 + label_width, value_width, height);
769 + }
770 +
771 + buffer_sprintf(wb,
772 "<rect class=\"bdge-ttl-width\" width=\"%0.2f\" height=\"%0.2f\" fill=\"url(#smooth)\"/>"
773 "</g>"
774 "<g fill=\"#fff\" text-anchor=\"middle\" font-family=\"DejaVu Sans,Verdana,Geneva,sans-serif\" font-size=\"%0.2f\">"
748 - "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
749 - "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\">%s</text>"
750 - "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\">%s</text>"
751 - "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\">%s</text>"
752 - "</g>"
775 + "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\" clip-path=\"url(#lbl-rect)\">%s</text>"
776 + "<text class=\"bdge-lbl-lbl\" x=\"%0.2f\" y=\"%0.0f\" clip-path=\"url(#lbl-rect)\">%s</text>"
777 + "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\" fill=\"#010101\" fill-opacity=\".3\" clip-path=\"url(#val-rect)\">%s</text>"
778 + "<text class=\"bdge-lbl-val\" x=\"%0.2f\" y=\"%0.0f\" clip-path=\"url(#val-rect)\">%s</text>"
779 + "</g>",
780 + total_width, height,
781 + font_size,
782 + label_width / 2, ceil(height - text_offset), label_escaped,
783 + label_width / 2, ceil(height - text_offset - 1.0), label_escaped,
784 + label_width + value_width / 2 -1, ceil(height - text_offset), value_escaped,
785 + label_width + value_width / 2 -1, ceil(height - text_offset - 1.0), value_escaped);
786 +
787 + if(fixed_width_lbl <= 0 || fixed_width_val <= 0){
788 + buffer_sprintf(wb,
789 "<script type=\"text/javascript\">"
790 "var bdg_horiz_padding = %d;"
791 "function netdata_bdge_each(list, attr, value){"
@@ -773,19 +809,10 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
809 "var width_update_elems = this_svg.getElementsByClassName(\"bdge-ttl-width\");"
810 "netdata_bdge_each(width_update_elems, \"width\", width_total);"
811 "this_svg.setAttribute(\"width\", width_total);"
776 - "</script>"
777 - "</svg>",
778 - total_width, height,
779 - total_width, height, round_corner,
780 - label_width, height, label_color_escaped,
781 - label_width, value_width, height, value_color_escaped,
782 - total_width, height,
783 - font_size,
784 - label_width / 2, ceil(height - text_offset), label_escaped,
785 - label_width / 2, ceil(height - text_offset - 1.0), label_escaped,
786 - label_width + value_width / 2 -1, ceil(height - text_offset), value_escaped,
787 - label_width + value_width / 2 -1, ceil(height - text_offset - 1.0), value_escaped,
788 - BADGE_HORIZONTAL_PADDING );
812 + "</script>",
813 + BADGE_HORIZONTAL_PADDING);
814 + }
815 + buffer_sprintf(wb, "</svg>");
816 }
817
818 int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *url) {
@@ -807,7 +834,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
834 , *refresh_str = NULL
835 , *precision_str = NULL
836 , *scale_str = NULL
810 - , *alarm = NULL;
837 + , *alarm = NULL
838 + , *fixed_width_lbl_str = NULL
839 + , *fixed_width_val_str = NULL;
840
841 int group = RRDR_GROUPING_AVERAGE;
842 uint32_t options = 0x00000000;
@@ -851,9 +880,20 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
880 else if(!strcmp(name, "refresh")) refresh_str = value;
881 else if(!strcmp(name, "precision")) precision_str = value;
882 else if(!strcmp(name, "scale")) scale_str = value;
883 + else if(!strcmp(name, "fixed_width_lbl")) fixed_width_lbl_str = value;
884 + else if(!strcmp(name, "fixed_width_val")) fixed_width_val_str = value;
885 else if(!strcmp(name, "alarm")) alarm = value;
886 }
887
888 + int fixed_width_lbl = -1;
889 + int fixed_width_val = -1;
890 +
891 + if(fixed_width_lbl_str && *fixed_width_lbl_str
892 + && fixed_width_val_str && *fixed_width_val_str) {
893 + fixed_width_lbl = str2i(fixed_width_lbl_str);
894 + fixed_width_val = str2i(fixed_width_val_str);
895 + }
896 +
897 if(!chart || !*chart) {
898 buffer_no_cacheable(w->response.data);
899 buffer_sprintf(w->response.data, "No chart id is given at the request.");
@@ -866,7 +906,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
906 if(!st) st = rrdset_find_byname(host, chart);
907 if(!st) {
908 buffer_no_cacheable(w->response.data);
869 - buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1, scale, 0);
909 + buffer_svg(w->response.data, "chart not found", NAN, "", NULL, NULL, -1, scale, 0, -1, -1);
910 ret = HTTP_RESP_OK;
911 goto cleanup;
912 }
@@ -877,7 +917,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
917 rc = rrdcalc_find(st, alarm);
918 if (!rc) {
919 buffer_no_cacheable(w->response.data);
880 - buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1, scale, 0);
920 + buffer_svg(w->response.data, "alarm not found", NAN, "", NULL, NULL, -1, scale, 0, -1, -1);
921 ret = HTTP_RESP_OK;
922 goto cleanup;
923 }
@@ -995,7 +1035,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
1035 value_color,
1036 precision,
1037 scale,
998 - options
1038 + options,
1039 + fixed_width_lbl,
1040 + fixed_width_val
1041 );
1042 ret = HTTP_RESP_OK;
1043 }
@@ -1032,7 +1074,9 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
1074 value_color,
1075 precision,
1076 scale,
1035 - options
1077 + options,
1078 + fixed_width_lbl,
1079 + fixed_width_val
1080 );
1081 }
1082
web/api/badges/web_buffer_svg.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "libnetdata/libnetdata.h"
7 #include "web/server/web_client.h"
8
9 -extern void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options);
9 +extern void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int precision, int scale, uint32_t options, int fixed_width_lbl, int fixed_width_val);
10 extern char *format_value_and_unit(char *value_string, size_t value_string_len, calculated_number value, const char *units, int precision);
11
12 extern int web_client_api_request_v1_badge(struct rrdhost *host, struct web_client *w, char *url);