typedef struct rrdresult {
RRDSET *st; // the chart this result refers to
- int group; // how many collected values were grouped for each row
- int update_every; // what is the suggested update frequency in seconds
-
int d; // the number of dimensions
int n; // the number of values in the arrays
int rows; // the number of rows used
int c; // current line ( -1 ~ n ), ( -1 = none, use rrdr_rows() to get number of rows )
+ int group; // how many collected values were grouped for each row
+ int update_every; // what is the suggested update frequency in seconds
+
+ calculated_number min;
+ calculated_number max;
+
+ time_t before;
+ time_t after;
+
int has_st_lock; // if st is read locked by us
} RRDR;
}
}
+void rrdr_buffer_print_format(BUFFER *wb, uint32_t format)
+{
+ switch(format) {
+ case DATASOURCE_JSON:
+ buffer_strcat(wb, DATASOURCE_FORMAT_JSON);
+ break;
+
+ case DATASOURCE_DATATABLE_JSON:
+ buffer_strcat(wb, DATASOURCE_FORMAT_DATATABLE_JSON);
+ break;
+
+ case DATASOURCE_DATATABLE_JSONP:
+ buffer_strcat(wb, DATASOURCE_FORMAT_DATATABLE_JSONP);
+ break;
+
+ case DATASOURCE_JSONP:
+ buffer_strcat(wb, DATASOURCE_FORMAT_JSONP);
+ break;
+
+ case DATASOURCE_SSV:
+ buffer_strcat(wb, DATASOURCE_FORMAT_SSV);
+ break;
+
+ case DATASOURCE_CSV:
+ buffer_strcat(wb, DATASOURCE_FORMAT_CSV);
+ break;
+
+ case DATASOURCE_TSV:
+ buffer_strcat(wb, DATASOURCE_FORMAT_TSV);
+ break;
+
+ case DATASOURCE_HTML:
+ buffer_strcat(wb, DATASOURCE_FORMAT_HTML);
+ break;
+
+ case DATASOURCE_JS_ARRAY:
+ buffer_strcat(wb, DATASOURCE_FORMAT_JS_ARRAY);
+ break;
+
+ case DATASOURCE_SSV_COMMA:
+ buffer_strcat(wb, DATASOURCE_FORMAT_SSV_COMMA);
+ break;
+
+ default:
+ buffer_strcat(wb, "unknown");
+ break;
+ }
+}
+
+void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value)
+{
+ char kq[2] = "", // key quote
+ sq[2] = ""; // string quote
+
+ if( options & RRDR_OPTION_GOOGLE_JSON ) {
+ kq[0] = '\0';
+ sq[0] = '\'';
+ }
+ else {
+ kq[0] = '"';
+ sq[0] = '"';
+ }
+
+ buffer_sprintf(wb, "{\n"
+ " %sid%s: %s%s%s,\n"
+ " %sname%s: %s%s%s,\n"
+ " %supdate_every%s: %d,\n"
+ " %smin%s: "
+ , kq, kq, sq, r->st->id, sq
+ , kq, kq, sq, r->st->name, sq
+ , kq, kq, r->update_every
+ , kq, kq);
+
+ buffer_rrd_value(wb, r->min);
+ buffer_sprintf(wb, ",\n %smax%s: ", kq, kq);
+ buffer_rrd_value(wb, r->max);
+ buffer_sprintf(wb, ",\n"
+ " %sbefore%s: %u,\n"
+ " %safter%s: %u,\n"
+ " %sdimension_names%s: ["
+ , kq, kq, r->before
+ , kq, kq, r->after
+ , kq, kq);
+
+
+ long c, i;
+ RRDDIM *rd;
+ for(c = 0, i = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
+ if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
+ if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_NONZERO))) continue;
+
+ if(i) buffer_strcat(wb, ", ");
+ buffer_strcat(wb, sq);
+ buffer_strcat(wb, rd->name);
+ buffer_strcat(wb, sq);
+ i++;
+ }
+ buffer_sprintf(wb, "],\n"
+ " %sdimension_ids%s: ["
+ , kq, kq);
+
+ for(c = 0, i = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
+ if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
+ if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_NONZERO))) continue;
+
+ if(i) buffer_strcat(wb, ", ");
+ buffer_strcat(wb, sq);
+ buffer_strcat(wb, rd->id);
+ buffer_strcat(wb, sq);
+ i++;
+ }
+ buffer_sprintf(wb, "],\n"
+ " %sdimensions%s: %d,\n"
+ " %spoints%s: %d,\n"
+ " %sformat%s: %s"
+ , kq, kq, i
+ , kq, kq, rrdr_rows(r)
+ , kq, kq, sq
+ );
+
+ rrdr_buffer_print_format(wb, format);
+
+ buffer_sprintf(wb, "%s,\n"
+ " %sresult%s: "
+ , sq
+ , kq, kq
+ );
+
+ if(string_value) buffer_strcat(wb, sq);
+}
+
+void rrdr_json_wrapper_end(RRDR *r, BUFFER *wb, uint32_t format, uint32_t options, int string_value)
+{
+ if(r) {;}
+ if(format) {;}
+
+ char sq[2] = ""; // string quote
+
+ if( options & RRDR_OPTION_GOOGLE_JSON )
+ sq[0] = '\'';
+ else
+ sq[0] = '"';
+
+ if(string_value) buffer_strcat(wb, sq);
+ buffer_strcat(wb, "\n}\n");
+}
+
#define JSON_DATES_JS 1
#define JSON_DATES_TIMESTAMP 2
snprintf(overflow_annotation, 200, ",{%sv%s:%sRESET OR OVERFLOW%s},{%sv%s:%sThe counters have been wrapped.%s}", kq, kq, sq, sq, kq, kq, sq, sq);
snprintf(normal_annotation, 200, ",{%sv%s:null},{%sv%s:null}", kq, kq, kq, kq);
- buffer_sprintf(wb, "{\n %supdate_every%s: %d,\n %scols%s:\n [\n", kq, kq, r->update_every, kq, kq, kq, kq);
+ buffer_sprintf(wb, "{\n %scols%s:\n [\n", kq, kq, kq, kq);
buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%stime%s,%spattern%s:%s%s,%stype%s:%sdatetime%s},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq);
buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotation%s}},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotationText%s}}", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
snprintf(data_begin, 100, "],\n %sdata%s:\n [\n", kq, kq);
snprintf(finish, 100, "\n ]\n}\n");
- buffer_sprintf(wb, "{\n %supdate_every%s: %d,\n %slabels%s: [", kq, kq, r->update_every, kq, kq);
+ buffer_sprintf(wb, "{\n %slabels%s: [", kq, kq);
buffer_sprintf(wb, "%stime%s", sq, sq);
}
}
}
-static void rrdr2ssv(RRDR *r, BUFFER *out, uint32_t options, const char *prefix, const char *separator, const char *suffix)
+static void rrdr2ssv(RRDR *r, BUFFER *wb, uint32_t options, const char *prefix, const char *separator, const char *suffix)
{
long c, i;
RRDDIM *d;
- buffer_strcat(out, prefix);
+ buffer_strcat(wb, prefix);
long start = 0, end = rrdr_rows(r), step = 1;
if((options & RRDR_OPTION_REVERSED)) {
start = rrdr_rows(r) - 1;
}
if(likely(i != start))
- buffer_strcat(out, separator);
+ buffer_strcat(wb, separator);
if(all_null) {
if(options & RRDR_OPTION_NULL2ZERO)
- buffer_strcat(out, "0");
+ buffer_strcat(wb, "0");
else
- buffer_strcat(out, "null");
+ buffer_strcat(wb, "null");
}
else if(options & RRDR_OPTION_MIN2MAX)
- buffer_rrd_value(out, max - min);
+ buffer_rrd_value(wb, max - min);
else
- buffer_rrd_value(out, sum);
+ buffer_rrd_value(wb, sum);
}
- buffer_strcat(out, suffix);
+ buffer_strcat(wb, suffix);
}
inline static calculated_number *rrdr_line_values(RRDR *r)
return NULL;
}
- RRDR *r = calloc(1, sizeof(RRDR));
+ RRDR *r = malloc(sizeof(RRDR));
if(unlikely(!r)) goto cleanup;
r->st = st;
+ r->has_st_lock = 0;
rrdr_lock_rrdset(r);
r->n = n;
- r->t = calloc(n, sizeof(time_t));
+ r->t = malloc(n * sizeof(time_t));
if(unlikely(!r->t)) goto cleanup;
- r->v = calloc(n * r->d, sizeof(calculated_number));
+ r->v = malloc(n * r->d * sizeof(calculated_number));
if(unlikely(!r->v)) goto cleanup;
- r->o = calloc(n * r->d, sizeof(uint8_t));
+ r->o = malloc(n * r->d * sizeof(uint8_t));
if(unlikely(!r->o)) goto cleanup;
- r->od = calloc(r->d, sizeof(uint8_t));
+ r->od = malloc(r->d * sizeof(uint8_t));
if(unlikely(!r->od)) goto cleanup;
r->c = -1;
r->rows = 0;
+ r->group = 1;
+ r->update_every = 1;
+
+ r->min = 0.0;
+ r->max = 0.0;
+
+ r->before = 0;
+ r->after = 0;
+
return r;
cleanup:
if(unlikely(now > before)) continue;
if(unlikely(now < after)) break;
- if(unlikely(group_count == 0)) group_start_t = now;
+ if(unlikely(group_count == 0)) {
+ group_start_t = now;
+ if(unlikely(!r->before)) {
+ r->before = group_start_t;
+ r->after = group_start_t;
+ }
+ }
group_count++;
if(unlikely(group_count == group)) {
if(unlikely(add_this)) {
if(unlikely(!rrdr_line_init(r, group_start_t))) break;
+ r->after = group_start_t;
+
calculated_number *cn = rrdr_line_values(r);
uint8_t *co = rrdr_line_options(r);
cn[c] = group_values[c];
}
+ if(cn[c] < r->min) r->min = cn[c];
+ if(cn[c] > r->max) r->max = cn[c];
+
// reset them for the next loop
group_values[c] = 0;
group_counts[c] = 0;
add_this = 0;
}
}
+ r->after += group * st->update_every;
rrdr_done(r);
//error("SHIFT: %s: wanted %ld points, got %ld", st->id, points, rrdr_rows(r));
return r;
}
-int rrd2format(RRDSET *st, BUFFER *out, BUFFER *dimensions, uint32_t format, long points, long long after, long long before, int group_method, uint32_t options, time_t *latest_timestamp)
+int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long points, long long after, long long before, int group_method, uint32_t options, time_t *latest_timestamp)
{
- RRDR *rrdr = rrd2rrdr(st, points, after, before, group_method);
- if(!rrdr) {
- buffer_strcat(out, "Cannot generate output with these parameters on this chart.");
+ RRDR *r = rrd2rrdr(st, points, after, before, group_method);
+ if(!r) {
+ buffer_strcat(wb, "Cannot generate output with these parameters on this chart.");
return 500;
}
if(dimensions)
- rrdr_disable_not_selected_dimensions(rrdr, buffer_tostring(dimensions));
+ rrdr_disable_not_selected_dimensions(r, buffer_tostring(dimensions));
- if(latest_timestamp && rrdr_rows(rrdr) > 0)
- *latest_timestamp = rrdr->t[rrdr_rows(rrdr) - 1];
+ if(latest_timestamp && rrdr_rows(r) > 0)
+ *latest_timestamp = r->before;
switch(format) {
case DATASOURCE_SSV:
- out->contenttype = CT_TEXT_PLAIN;
- rrdr2ssv(rrdr, out, options, "", " ", "");
+ if(options & RRDR_OPTION_JSON_WRAP) {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr_json_wrapper_begin(r, wb, format, options, 1);
+ rrdr2ssv(r, wb, options, "", " ", "");
+ rrdr_json_wrapper_end(r, wb, format, options, 1);
+ }
+ else {
+ wb->contenttype = CT_TEXT_PLAIN;
+ rrdr2ssv(r, wb, options, "", " ", "");
+ }
break;
case DATASOURCE_SSV_COMMA:
- out->contenttype = CT_TEXT_PLAIN;
- rrdr2ssv(rrdr, out, options, "", ",", "");
+ if(options & RRDR_OPTION_JSON_WRAP) {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr_json_wrapper_begin(r, wb, format, options, 1);
+ rrdr2ssv(r, wb, options, "", ",", "");
+ rrdr_json_wrapper_end(r, wb, format, options, 1);
+ }
+ else {
+ wb->contenttype = CT_TEXT_PLAIN;
+ rrdr2ssv(r, wb, options, "", ",", "");
+ }
break;
case DATASOURCE_JS_ARRAY:
- out->contenttype = CT_APPLICATION_JSON;
- rrdr2ssv(rrdr, out, options, "[", ",", "]");
+ if(options & RRDR_OPTION_JSON_WRAP) {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr_json_wrapper_begin(r, wb, format, options, 0);
+ rrdr2ssv(r, wb, options, "[", ",", "]");
+ rrdr_json_wrapper_end(r, wb, format, options, 0);
+ }
+ else {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr2ssv(r, wb, options, "[", ",", "]");
+ }
break;
case DATASOURCE_CSV:
- out->contenttype = CT_TEXT_PLAIN;
- rrdr2csv(rrdr, out, options, "", ",", "\r\n");
+ if(options & RRDR_OPTION_JSON_WRAP) {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr_json_wrapper_begin(r, wb, format, options, 1);
+ rrdr2csv(r, wb, options, "", ",", "\\n");
+ rrdr_json_wrapper_end(r, wb, format, options, 1);
+ }
+ else {
+ wb->contenttype = CT_TEXT_PLAIN;
+ rrdr2csv(r, wb, options, "", ",", "\r\n");
+ }
break;
case DATASOURCE_TSV:
- out->contenttype = CT_TEXT_PLAIN;
- rrdr2csv(rrdr, out, options, "", "\t", "\r\n");
+ if(options & RRDR_OPTION_JSON_WRAP) {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr_json_wrapper_begin(r, wb, format, options, 1);
+ rrdr2csv(r, wb, options, "", "\t", "\\n");
+ rrdr_json_wrapper_end(r, wb, format, options, 1);
+ }
+ else {
+ wb->contenttype = CT_TEXT_PLAIN;
+ rrdr2csv(r, wb, options, "", "\t", "\r\n");
+ }
break;
case DATASOURCE_HTML:
- out->contenttype = CT_TEXT_HTML;
- buffer_strcat(out, "<html>\n<center><table border=\"0\" cellpadding=\"5\" cellspacing=\"5\">");
- rrdr2csv(rrdr, out, options, "<tr><td>", "</td><td>", "</td></tr>\n");
- buffer_strcat(out, "</table>\n</center>\n</html>\n");
+ if(options & RRDR_OPTION_JSON_WRAP) {
+ wb->contenttype = CT_APPLICATION_JSON;
+ rrdr_json_wrapper_begin(r, wb, format, options, 1);
+ buffer_strcat(wb, "<html>\\n<center>\\n<table border=\\\"0\\\" cellpadding=\\\"5\\\" cellspacing=\\\"5\\\">\\n");
+ rrdr2csv(r, wb, options, "<tr><td>", "</td><td>", "</td></tr>\\n");
+ buffer_strcat(wb, "</table>\\n</center>\\n</html>\\n");
+ rrdr_json_wrapper_end(r, wb, format, options, 1);
+ }
+ else {
+ wb->contenttype = CT_TEXT_HTML;
+ buffer_strcat(wb, "<html>\n<center>\n<table border=\"0\" cellpadding=\"5\" cellspacing=\"5\">\n");
+ rrdr2csv(r, wb, options, "<tr><td>", "</td><td>", "</td></tr>\n");
+ buffer_strcat(wb, "</table>\n</center>\n</html>\n");
+ }
break;
case DATASOURCE_DATATABLE_JSONP:
- out->contenttype = CT_APPLICATION_X_JAVASCRIPT;
- rrdr2json(rrdr, out, options, 1);
+ wb->contenttype = CT_APPLICATION_X_JAVASCRIPT;
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_begin(r, wb, format, options, 0);
+
+ rrdr2json(r, wb, options, 1);
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_end(r, wb, format, options, 0);
break;
case DATASOURCE_DATATABLE_JSON:
- out->contenttype = CT_APPLICATION_JSON;
- rrdr2json(rrdr, out, options, 1);
+ wb->contenttype = CT_APPLICATION_JSON;
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_begin(r, wb, format, options, 0);
+
+ rrdr2json(r, wb, options, 1);
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_end(r, wb, format, options, 0);
break;
case DATASOURCE_JSONP:
- out->contenttype = CT_APPLICATION_X_JAVASCRIPT;
- rrdr2json(rrdr, out, options, 0);
+ wb->contenttype = CT_APPLICATION_X_JAVASCRIPT;
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_begin(r, wb, format, options, 0);
+
+ rrdr2json(r, wb, options, 0);
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_end(r, wb, format, options, 0);
break;
case DATASOURCE_JSON:
default:
- out->contenttype = CT_APPLICATION_JSON;
- rrdr2json(rrdr, out, options, 0);
+ wb->contenttype = CT_APPLICATION_JSON;
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_begin(r, wb, format, options, 0);
+
+ rrdr2json(r, wb, options, 0);
+
+ if(options & RRDR_OPTION_JSON_WRAP)
+ rrdr_json_wrapper_end(r, wb, format, options, 0);
break;
}
- rrdr_free(rrdr);
+ rrdr_free(r);
return 200;
}
#define DATASOURCE_JS_ARRAY 8
#define DATASOURCE_SSV_COMMA 9
+#define DATASOURCE_FORMAT_JSON "json"
+#define DATASOURCE_FORMAT_DATATABLE_JSON "datatable"
+#define DATASOURCE_FORMAT_DATATABLE_JSONP "datasource"
+#define DATASOURCE_FORMAT_JSONP "jsonp"
+#define DATASOURCE_FORMAT_SSV "ssv"
+#define DATASOURCE_FORMAT_CSV "csv"
+#define DATASOURCE_FORMAT_TSV "tsv"
+#define DATASOURCE_FORMAT_HTML "html"
+#define DATASOURCE_FORMAT_JS_ARRAY "array"
+#define DATASOURCE_FORMAT_SSV_COMMA "ssvcomma"
+
#define GROUP_AVERAGE 0
#define GROUP_MAX 1
#define GROUP_SUM 2
#define RRDR_OPTION_NULL2ZERO 0x00000040 // do not show nulls, convert them to zeros
#define RRDR_OPTION_OBJECTSROWS 0x00000080 // each row of values should be an object, not an array
#define RRDR_OPTION_GOOGLE_JSON 0x00000100 // comply with google JSON/JSONP specs
+#define RRDR_OPTION_JSON_WRAP 0x00000200 // wrap the response in a JSON header with info about the result
extern void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb);
extern void rrd_stats_api_v1_charts(BUFFER *wb);
ret |= RRDR_OPTION_NONZERO;
else if(!strcmp(tok, "flip") || !strcmp(tok, "reversed") || !strcmp(tok, "reverse"))
ret |= RRDR_OPTION_REVERSED;
- else if(!strcmp(tok, "abs") || !strcmp(tok, "absolute") || !strcmp(tok, "absolute_sum") || !strcmp(tok, "absolute-sum"))
- ret |= RRDR_OPTION_ABSOLUTE;
+ else if(!strcmp(tok, "jsonwrap"))
+ ret |= RRDR_OPTION_JSON_WRAP;
else if(!strcmp(tok, "min2max"))
ret |= RRDR_OPTION_MIN2MAX;
- else if(!strcmp(tok, "seconds"))
- ret |= RRDR_OPTION_SECONDS;
else if(!strcmp(tok, "ms") || !strcmp(tok, "milliseconds"))
ret |= RRDR_OPTION_MILLISECONDS;
+ else if(!strcmp(tok, "abs") || !strcmp(tok, "absolute") || !strcmp(tok, "absolute_sum") || !strcmp(tok, "absolute-sum"))
+ ret |= RRDR_OPTION_ABSOLUTE;
+ else if(!strcmp(tok, "seconds"))
+ ret |= RRDR_OPTION_SECONDS;
else if(!strcmp(tok, "null2zero"))
ret |= RRDR_OPTION_NULL2ZERO;
else if(!strcmp(tok, "objectrows"))
int web_client_api_request_v1_data_format(char *name)
{
- if(!strcmp(name, "datatable"))
+ if(!strcmp(name, DATASOURCE_FORMAT_DATATABLE_JSON)) // datatable
return DATASOURCE_DATATABLE_JSON;
- else if(!strcmp(name, "datasource"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_DATATABLE_JSONP)) // datasource
return DATASOURCE_DATATABLE_JSONP;
- else if(!strcmp(name, "json"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_JSON)) // json
return DATASOURCE_JSON;
- else if(!strcmp(name, "jsonp"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_JSONP)) // jsonp
return DATASOURCE_JSONP;
- else if(!strcmp(name, "ssv"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_SSV)) // ssv
return DATASOURCE_SSV;
- else if(!strcmp(name, "csv"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_CSV)) // csv
return DATASOURCE_CSV;
- else if(!strcmp(name, "tsv"))
- return DATASOURCE_TSV;
-
- else if(!strcmp(name, "tsv-excel"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_TSV)) // tsv
return DATASOURCE_TSV;
- else if(!strcmp(name, "html"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_HTML)) // html
return DATASOURCE_HTML;
- else if(!strcmp(name, "array"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_JS_ARRAY)) // array
return DATASOURCE_JS_ARRAY;
- else if(!strcmp(name, "ssvcomma"))
+ else if(!strcmp(name, DATASOURCE_FORMAT_SSV_COMMA)) // ssvcomma
return DATASOURCE_SSV_COMMA;
+ else if(!strcmp(name, "tsv-excel"))
+ return DATASOURCE_TSV;
+
return DATASOURCE_JSON;
}
</head>
<body>
-<h1>NetData Custom Dashboard</h1>
+<h1>NetData Custom Dashboard <div data-netdata="system.cpu" data-chart-library="sparkline" data-height="30" data-after="-600" data-sparkline-linecolor="#888"></div></h1>
This is a template for building custom dashboards. To build a dashboard you just do this:
data-chart-library="sparkline"
data-width="100%"
data-height="30"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time101"
></div>
<br/>
data-chart-library="sparkline"
data-width="100%"
data-height="30"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time102"
></div>
<br/>
data-chart-library="sparkline"
data-width="100%"
data-height="30"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time103"
></div>
<br/>
data-chart-library="peity"
data-width="100%"
data-height="30"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time001"
></div>
<br/>
data-chart-library="peity"
data-width="100%"
data-height="30"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time002"
></div>
<br/>
data-chart-library="peity"
data-width="100%"
data-height="30"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time003"
></div>
<br/>
data-chart-library="dygraph"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time201"
></div>
<br/>
data-chart-library="dygraph"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time202"
></div>
<br/>
data-chart-library="dygraph"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time203"
></div>
<br/>
data-chart-library="google"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time301"
></div>
<br/>
data-chart-library="google"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time302"
></div>
<br/>
data-chart-library="google"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time303"
></div>
<br/>
data-chart-library="morris"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time401"
></div>
<br/>
data-chart-library="morris"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time402"
></div>
<br/>
data-chart-library="morris"
data-width="100%"
data-height="200"
- data-after="-600"
+ data-after="-300"
data-dt-element-name="time403"
></div>
<br/>
NETDATA.options = {
targets: null,
updated_dom: 1,
- debug: 0,
last_paused: 0,
+ page_is_visible: 1,
current: {
pixels_per_point: 1,
idle_between_charts: 100,
idle_between_loops: 500,
+ idle_lost_focus: 500,
fast_render_timeframe: 200 // render continously for these many ms
+ },
+
+ debug: {
+ show_boxes: 0,
+ main_loop: 0,
+ focus: 1,
+ visibility: 0,
+ chart_data_url: 1,
+ chart_errors: 1,
+ chart_timing: 0,
+ chart_calls: 0,
}
}
- if(NETDATA.options.debug) console.log('welcome to NETDATA');
+ if(NETDATA.options.debug.main_loop) console.log('welcome to NETDATA');
// ----------------------------------------------------------------------------------------------------------------
self = $(element);
bgcolor = ""
- if(NETDATA.options.debug)
+ if(NETDATA.options.debug.show_boxes)
bgcolor = " background-color: lightgrey;";
- element.innerHTML = '<div style="overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
+ element.innerHTML = '<div style="font-size: xx-small; overflow: hidden;' + bgcolor + ' width: 100%; height: 100%;"><small>'
+ message
+ '</small></div>';
}
// ----------------------------------------------------------------------------------------------------------------
+ // Library functions
+
// Load a script without jquery
// This is used to load jquery - after it is loaded, we use jquery
-
NETDATA._loadjQuery = function(callback) {
if(typeof jQuery == 'undefined') {
var script = document.createElement('script');
callback();
}
+ NETDATA.ColorLuminance = function(hex, lum) {
+ // validate hex string
+ hex = String(hex).replace(/[^0-9a-f]/gi, '');
+ if (hex.length < 6)
+ hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
+
+ lum = lum || 0;
+
+ // convert to decimal and change luminosity
+ var rgb = "#", c, i;
+ for (i = 0; i < 3; i++) {
+ c = parseInt(hex.substr(i*2,2), 16);
+ c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
+ rgb += ("00"+c).substr(c.length);
+ }
+
+ return rgb;
+ }
+
+ NETDATA.guid = function() {
+ function s4() {
+ return Math.floor((1 + Math.random()) * 0x10000)
+ .toString(16)
+ .substring(1);
+ }
+
+ return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
+ }
+
+ // this is the main function - where everything starts
+ NETDATA.init = function() {
+ // this should be called only once
+
+ $(window).blur(function() {
+ NETDATA.options.page_is_visible = 0;
+ if(NETDATA.options.debug.focus) console.log('Lost Focus!');
+ });
+
+ $(window).focus(function() {
+ NETDATA.options.page_is_visible = 1;
+ if(NETDATA.options.debug.focus) console.log('Focus restored!');
+ });
+
+ NETDATA.getDomCharts(function() {
+ NETDATA.chartRefresher(0);
+ });
+ }
+
+ // user function to signal us the DOM has been
+ // updated.
+ NETDATA.updatedDom = function() {
+ NETDATA.options.updated_dom = 1;
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+
NETDATA.generateChartDataURL = function() {
self = $(this);
pixels_per_point = NETDATA.options.current.pixels_per_point
var points = self.data('points') || Math.round(width / pixels_per_point);
+ var format = self.data('format') || NETDATA.chartLibraries[library].format;
+ var options = self.data('options') || NETDATA.chartLibraries[library].options;
// build the data URL
var url = host + chart.data_url;
- url += "&format=" + NETDATA.chartLibraries[library].format;
+ url += "&format=" + format;
url += "&points=" + points.toString();
- url += "&options=" + NETDATA.chartLibraries[library].options;
+ url += "&options=" + options;
url += "&group=" + method;
if(after)
.data('calculated-points', points)
.data('calculated-url', url);
- if(NETDATA.options.debug) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
+ if(NETDATA.options.debug.chart_data_url) console.log('generateChartDataURL(): ' + url + ' WxH:' + width + 'x' + height + ' points: ' + points + ' library: ' + library);
return url;
}
NETDATA.validateDomCharts = function(targets, index, callback) {
- if(NETDATA.options.debug) console.log('validateDomCharts() working on ' + index);
+ if(NETDATA.options.debug.main_loop) console.log('validateDomCharts() working on ' + index);
var target = targets.get(index);
if(target == null) {
- if(NETDATA.options.debug) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
+ if(NETDATA.options.debug.main_loop) console.log('validateDomCharts(): all ' + (index - 1) + ' charts parsed.');
if(typeof callback == 'function') callback();
}
else {
var host = self.data('host') || NETDATA.chartDefaults.host;
var library = self.data('chart-library') || NETDATA.chartDefaults.library;
- if(NETDATA.options.debug) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
+ if(NETDATA.options.debug.main_loop) console.log('validateDomCharts() parsing ' + id + ' of type ' + library);
if(typeof NETDATA.chartLibraries[library] == 'undefined') {
NETDATA.error(402, library);
NETDATA.sizeDomCharts = function(targets, index, callback) {
// this is used to quickly size all charts to their size
- if(NETDATA.options.debug) console.log('sizeDomCharts() working on ' + index);
+ if(NETDATA.options.debug.main_loop) console.log('sizeDomCharts() working on ' + index);
var target = targets.get(index);
if(target == null) {
- if(NETDATA.options.debug) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
+ if(NETDATA.options.debug.main_loop) console.log('sizeDomCharts(): all ' + (index - 1) + ' charts sized.');
if(typeof callback == 'function') callback();
}
else {
NETDATA.options.targets = $('div[data-netdata]').filter(':visible')
.bind('create', function(event, data) {
var self = $(this);
-
- if(NETDATA.options.debug)
+
+ if(NETDATA.options.debug.chart_errors)
NETDATA.chartLibraries[self.data('chart-library')].create(this, data);
else {
try {
})
.bind('update', function(event, data) {
var self = $(this);
- if(NETDATA.options.debug)
+ if(NETDATA.options.debug.chart_errors)
NETDATA.chartLibraries[self.data('chart-library')].update(this, data);
else {
try {
}
});
- if(NETDATA.options.debug)
+ if(NETDATA.options.debug.main_loop)
console.log('DOM updated - there are ' + NETDATA.options.targets.length + ' charts on page.');
NETDATA.sizeDomCharts(NETDATA.options.targets, 0, function() {
});
}
- NETDATA.init = function() {
- // this should be called only once
- NETDATA.getDomCharts(function() {
- NETDATA.chartRefresher(0);
- });
- }
-
// ----------------------------------------------------------------------------------------------------------------
//var chart = function() {
// check if this chart has to be refreshed now
var now = new Date().getTime();
if(last + every > now) {
- console.log(self.data('netdata') + ' too soon - skipping.');
+ if(NETDATA.options.debug.chart_timing) console.log(self.data('netdata') + ' too soon - skipping.');
if(typeof callback == 'function') callback();
}
else if(!self.visible(true)) {
- console.log(self.data('netdata') + ' is NOT visible.');
+ if(NETDATA.options.debug.visibility) console.log(self.data('netdata') + ' is NOT visible.');
if(typeof callback == 'function') callback();
}
else {
- console.log(self.data('netdata') + ' is visible, downloading data...');
+ if(NETDATA.options.debug.visibility) console.log(self.data('netdata') + ' is visible, downloading data...');
$.ajax( {
url: NETDATA.generateChartDataURL.call(element), // self.data('chart-url'),
crossDomain: true
.then(function(data) {
var started = new Date().getTime();
+ // if the result is JSON, find the latest update-every
+ if(NETDATA.chartLibraries[self.data('chart-library')].jsonWrapper &&
+ typeof data.update_every != 'undefined')
+ self.data('update-every', data.update_every * 1000);
+
if(self.data('created')) {
- console.log('updating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
+ if(NETDATA.options.debug.chart_calls) console.log('updating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
self.trigger('update', [data]);
// NETDATA.chartLibraries[self.data('chart-library')].update(element, data);
}
else {
- console.log('creating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
+ if(NETDATA.options.debug.chart_calls) console.log('creating ' + self.data('chart-library') + ' chart ' + self.data('netdata'));
self.trigger('create', [data]);
//NETDATA.chartLibraries[self.data('chart-library')].create(element, data);
self.data('created', true);
};
NETDATA.chartRefresher = function(index) {
- // if(NETDATA.options.debug) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
+ // if(NETDATA.options.debug.mail_loop) console.log('NETDATA.chartRefresher(<targets, ' + index + ')');
- now = new Date().getTime();
-
- if(NETDATA.options.updated_dom) {
- NETDATA.getDomCharts(function() {
- NETDATA.chartRefresher(0);
- });
+ if(!NETDATA.options.page_is_visible) {
+ if(NETDATA.options.debug.main_loop) console.log('waiting focus...');
+ setTimeout(function() {
+ NETDATA.chartRefresher(index);
+ }, NETDATA.options.current.idle_lost_focus);
}
else {
- var target = NETDATA.options.targets.get(index);
- if(target == null) {
- if(NETDATA.options.debug) console.log('waiting to restart main loop...');
- NETDATA.options.last_paused = now;
+ now = new Date().getTime();
- setTimeout(function() {
+ if(NETDATA.options.updated_dom) {
+ // the dom has been updated
+ // get the dom parts again
+ NETDATA.getDomCharts(function() {
NETDATA.chartRefresher(0);
- }, NETDATA.options.current.idle_between_loops);
+ });
}
else {
- var self = $(target);
- if(!self.data('enabled')) {
- NETDATA.chartRefresher(++index);
+ var target = NETDATA.options.targets.get(index);
+ if(target == null) {
+ if(NETDATA.options.debug.main_loop) console.log('waiting to restart main loop...');
+ NETDATA.options.last_paused = now;
+
+ setTimeout(function() {
+ NETDATA.chartRefresher(0);
+ }, NETDATA.options.current.idle_between_loops);
}
else {
- if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
- if(NETDATA.options.debug) console.log('fast rendering...');
-
- NETDATA.chartValuesDownloader(target, function() {
- NETDATA.chartRefresher(++index);
- });
+ var self = $(target);
+ if(!self.data('enabled')) {
+ NETDATA.chartRefresher(++index);
}
else {
- if(NETDATA.options.debug) console.log('waiting for next refresh...');
- NETDATA.options.last_paused = now;
+ if(now - NETDATA.options.last_paused < NETDATA.options.current.fast_render_timeframe) {
+ if(NETDATA.options.debug.main_loop) console.log('fast rendering...');
- setTimeout(function() {
NETDATA.chartValuesDownloader(target, function() {
NETDATA.chartRefresher(++index);
});
- }, NETDATA.options.current.idle_between_charts);
+ }
+ else {
+ if(NETDATA.options.debug.main_loop) console.log('waiting for next refresh...');
+ NETDATA.options.last_paused = now;
+
+ setTimeout(function() {
+ NETDATA.chartValuesDownloader(target, function() {
+ NETDATA.chartRefresher(++index);
+ });
+ }, NETDATA.options.current.idle_between_charts);
+ }
}
}
}
}
}
- NETDATA.guid = function() {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- }
-
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
- }
-
// ----------------------------------------------------------------------------------------------------------------
// peity
var self = $(element);
var instance = self.data('peity-instance');
var ins = $(instance);
- ins.html(data);
+ ins.html(data.result);
// peity.change() does not accept options
// to pass width and height
var self = $(element);
var uuid = NETDATA.guid();
- element.innerHTML = '<div id="' + uuid + '">' + data + '</div>';
+ element.innerHTML = '<div id="' + uuid + '">' + data.result + '</div>';
var instance = document.getElementById(uuid);
var ins = $(instance);
var options = self.data('sparkline-options');
options.width = self.data('calculated-width');
options.height = self.data('calculated-height');
- self.sparkline(data, options);
+ self.sparkline(data.result, options);
}
NETDATA.sparklineChartCreate = function(element, data) {
var self = $(element);
var chart = self.data('chart');
var type = self.data('sparkline-type') || 'line';
- var lineColor = self.data('sparkline-lineColor') || undefined;
- var fillColor = self.data('sparkline-fillColor') || (chart.chart_type == 'line')?'#FFF':undefined;
- var chartRangeMin = self.data('sparkline-chartRangeMin') || undefined;
- var chartRangeMax = self.data('sparkline-chartRangeMax') || undefined;
+ var lineColor = self.data('sparkline-linecolor') || NETDATA.colors[0];
+ var fillColor = self.data('sparkline-fillcolor') || (chart.chart_type == 'line')?'#FFF':NETDATA.ColorLuminance(lineColor, 0.8);
+ var chartRangeMin = self.data('sparkline-chartrangemin') || undefined;
+ var chartRangeMax = self.data('sparkline-chartrangemax') || undefined;
var composite = self.data('sparkline-composite') || undefined;
- var enableTagOptions = self.data('sparkline-enableTagOptions') || undefined;
- var tagOptionPrefix = self.data('sparkline-tagOptionPrefix') || undefined;
- var tagValuesAttribute = self.data('sparkline-tagValuesAttribute') || undefined;
- var disableHiddenCheck = self.data('sparkline-disableHiddenCheck') || undefined;
- var defaultPixelsPerValue = self.data('sparkline-defaultPixelsPerValue') || undefined;
- var spotColor = self.data('sparkline-spotColor') || undefined;
- var minSpotColor = self.data('sparkline-minSpotColor') || undefined;
- var maxSpotColor = self.data('sparkline-maxSpotColor') || undefined;
- var spotRadius = self.data('sparkline-spotRadius') || undefined;
- var valueSpots = self.data('sparkline-valueSpots') || undefined;
- var highlightSpotColor = self.data('sparkline-highlightSpotColor') || undefined;
- var highlightLineColor = self.data('sparkline-highlightLineColor') || undefined;
- var lineWidth = self.data('sparkline-lineWidth') || undefined;
- var normalRangeMin = self.data('sparkline-normalRangeMin') || undefined;
- var normalRangeMax = self.data('sparkline-normalRangeMax') || undefined;
- var drawNormalOnTop = self.data('sparkline-drawNormalOnTop') || undefined;
+ var enableTagOptions = self.data('sparkline-enabletagoptions') || undefined;
+ var tagOptionPrefix = self.data('sparkline-tagoptionprefix') || undefined;
+ var tagValuesAttribute = self.data('sparkline-tagvaluesattribute') || undefined;
+ var disableHiddenCheck = self.data('sparkline-disablehiddencheck') || undefined;
+ var defaultPixelsPerValue = self.data('sparkline-defaultpixelspervalue') || undefined;
+ var spotColor = self.data('sparkline-spotcolor') || undefined;
+ var minSpotColor = self.data('sparkline-minspotcolor') || undefined;
+ var maxSpotColor = self.data('sparkline-maxspotcolor') || undefined;
+ var spotRadius = self.data('sparkline-spotradius') || undefined;
+ var valueSpots = self.data('sparkline-valuespots') || undefined;
+ var highlightSpotColor = self.data('sparkline-highlightspotcolor') || undefined;
+ var highlightLineColor = self.data('sparkline-highlightlinecolor') || undefined;
+ var lineWidth = self.data('sparkline-linewidth') || undefined;
+ var normalRangeMin = self.data('sparkline-normalrangemin') || undefined;
+ var normalRangeMax = self.data('sparkline-normalrangemax') || undefined;
+ var drawNormalOnTop = self.data('sparkline-drawnormalontop') || undefined;
var xvalues = self.data('sparkline-xvalues') || undefined;
- var chartRangeClip = self.data('sparkline-chartRangeClip') || undefined;
+ var chartRangeClip = self.data('sparkline-chartrangeclip') || undefined;
var xvalues = self.data('sparkline-xvalues') || undefined;
- var chartRangeMinX = self.data('sparkline-chartRangeMinX') || undefined;
- var chartRangeMaxX = self.data('sparkline-chartRangeMaxX') || undefined;
- var disableInteraction = self.data('sparkline-disableInteraction') || false;
- var disableTooltips = self.data('sparkline-disableTooltips') || false;
- var disableHighlight = self.data('sparkline-disableHighlight') || false;
- var highlightLighten = self.data('sparkline-highlightLighten') || 1.4;
- var highlightColor = self.data('sparkline-highlightColor') || undefined;
- var tooltipContainer = self.data('sparkline-tooltipContainer') || undefined;
- var tooltipClassname = self.data('sparkline-tooltipClassname') || undefined;
- var tooltipFormat = self.data('sparkline-tooltipFormat') || undefined;
- var tooltipPrefix = self.data('sparkline-tooltipPrefix') || undefined;
- var tooltipSuffix = self.data('sparkline-tooltipSuffix') || ' ' + chart.units;
- var tooltipSkipNull = self.data('sparkline-tooltipSkipNull') || true;
- var tooltipValueLookups = self.data('sparkline-tooltipValueLookups') || undefined;
- var tooltipFormatFieldlist = self.data('sparkline-tooltipFormatFieldlist') || undefined;
- var tooltipFormatFieldlistKey = self.data('sparkline-tooltipFormatFieldlistKey') || undefined;
- var numberFormatter = self.data('sparkline-numberFormatter') || function(n){ return n.toFixed(2); };
- var numberDigitGroupSep = self.data('sparkline-numberDigitGroupSep') || undefined;
- var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;
- var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;
- var animatedZooms = self.data('sparkline-animatedZooms') || false;
+ var chartRangeMinX = self.data('sparkline-chartrangeminx') || undefined;
+ var chartRangeMaxX = self.data('sparkline-chartrangemaxx') || undefined;
+ var disableInteraction = self.data('sparkline-disableinteraction') || false;
+ var disableTooltips = self.data('sparkline-disabletooltips') || false;
+ var disableHighlight = self.data('sparkline-disablehighlight') || false;
+ var highlightLighten = self.data('sparkline-highlightlighten') || 1.4;
+ var highlightColor = self.data('sparkline-highlightcolor') || undefined;
+ var tooltipContainer = self.data('sparkline-tooltipcontainer') || undefined;
+ var tooltipClassname = self.data('sparkline-tooltipclassname') || undefined;
+ var tooltipFormat = self.data('sparkline-tooltipformat') || undefined;
+ var tooltipPrefix = self.data('sparkline-tooltipprefix') || undefined;
+ var tooltipSuffix = self.data('sparkline-tooltipsuffix') || ' ' + chart.units;
+ var tooltipSkipNull = self.data('sparkline-tooltipskipnull') || true;
+ var tooltipValueLookups = self.data('sparkline-tooltipvaluelookups') || undefined;
+ var tooltipFormatFieldlist = self.data('sparkline-tooltipformatfieldlist') || undefined;
+ var tooltipFormatFieldlistKey = self.data('sparkline-tooltipformatfieldlistkey') || undefined;
+ var numberFormatter = self.data('sparkline-numberformatter') || function(n){ return n.toFixed(2); };
+ var numberDigitGroupSep = self.data('sparkline-numberdigitgroupsep') || undefined;
+ var numberDecimalMark = self.data('sparkline-numberdecimalmark') || undefined;
+ var numberDigitGroupCount = self.data('sparkline-numberdigitgroupcount') || undefined;
+ var animatedZooms = self.data('sparkline-animatedzooms') || false;
var options = {
type: type,
element.innerHTML = '<div style="display: inline-block; position: relative;" id="' + uuid + '"></div>';
var div = document.getElementById(uuid);
- self.sparkline(data, options);
+ self.sparkline(data.result, options);
self.data('sparkline-options', options)
- .data('uuid', uuid)
- .data('created', true);
+ .data('uuid', uuid)
+ .data('created', true);
};
// ----------------------------------------------------------------------------------------------------------------
var self = $(element);
var dygraph = self.data('dygraph-instance');
- if(typeof data.update_every != 'undefined')
- self.data('update-every', data.update_every * 1000);
-
- if(dygraph != null) {
- console.log('updating dygraphs');
- dygraph.updateOptions({
- file: data.data,
- labels: data.labels,
- labelsDivWidth: self.width() - 70
- });
- }
- else
- console.log('not updating dygraphs');
+ dygraph.updateOptions({
+ file: data.result.data,
+ labels: data.result.labels,
+ labelsDivWidth: self.width() - 70
+ });
};
NETDATA.dygraphChartCreate = function(element, data) {
var self = $(element);
var chart = self.data('chart');
var title = self.data('dygraph-title') || chart.title;
- var titleHeight = self.data('dygraph-titleHeight') || 20;
- var labelsDiv = self.data('dygraph-labelsDiv') || undefined;
- var connectSeparatedPoints = self.data('dygraph-connectSeparatedPoints') || false;
- var yLabelWidth = self.data('dygraph-yLabelWidth') || 12;
- var stackedGraph = self.data('dygraph-stackedGraph') || (chart.chart_type == 'stacked')?true:false;
- var stackedGraphNaNFill = self.data('dygraph-stackedGraphNaNFill') || 'none';
- var hideOverlayOnMouseOut = self.data('dygraph-hideOverlayOnMouseOut') || true;
- var fillGraph = self.data('dygraph-fillGraph') || (chart.chart_type == 'area')?true:false;
- var drawPoints = self.data('dygraph-drawPoints') || false;
- var labelsDivStyles = self.data('dygraph-labelsDivStyles') || { 'fontSize':'10px' };
- // var labelsDivWidth = self.data('dygraph-labelsDivWidth') || 250;
- var labelsDivWidth = self.width() - 70;
- var labelsSeparateLines = self.data('dygraph-labelsSeparateLines') || false;
- var labelsShowZeroValues = self.data('dygraph-labelsShowZeroValues') || true;
+ var titleHeight = self.data('dygraph-titleheight') || 20;
+ var labelsDiv = self.data('dygraph-labelsdiv') || undefined;
+ var connectSeparatedPoints = self.data('dygraph-connectseparatedpoints') || false;
+ var yLabelWidth = self.data('dygraph-ylabelwidth') || 12;
+ var stackedGraph = self.data('dygraph-stackedgraph') || (chart.chart_type == 'stacked')?true:false;
+ var stackedGraphNaNFill = self.data('dygraph-stackedgraphnanfill') || 'none';
+ var hideOverlayOnMouseOut = self.data('dygraph-hideoverlayonmouseout') || true;
+ var fillGraph = self.data('dygraph-fillgraph') || (chart.chart_type == 'area')?true:false;
+ var drawPoints = self.data('dygraph-drawpoints') || false;
+ var labelsDivStyles = self.data('dygraph-labelsdivstyles') || { 'fontSize':'10px' };
+ var labelsDivWidth = self.data('dygraph-labelsdivwidth') || self.width() - 70;
+ var labelsSeparateLines = self.data('dygraph-labelsseparatelines') || false;
+ var labelsShowZeroValues = self.data('dygraph-labelsshowzerovalues') || true;
var legend = self.data('dygraph-legend') || 'onmouseover';
- var showLabelsOnHighlight = self.data('dygraph-showLabelsOnHighlight') || true;
- var gridLineColor = self.data('dygraph-gridLineColor') || '#EEE';
- var axisLineColor = self.data('dygraph-axisLineColor') || '#EEE';
- var maxNumberWidth = self.data('dygraph-maxNumberWidth') || 8;
- var sigFigs = self.data('dygraph-sigFigs') || null;
- var digitsAfterDecimal = self.data('dygraph-digitsAfterDecimal') || 2;
- var axisLabelFontSize = self.data('dygraph-axisLabelFontSize') || 10;
- var axisLineWidth = self.data('dygraph-axisLineWidth') || 0.3;
- var drawAxis = self.data('dygraph-drawAxis') || true;
- var strokeWidth = self.data('dygraph-strokeWidth') || 1.0;
- var drawGapEdgePoints = self.data('dygraph-drawGapEdgePoints') || true;
+ var showLabelsOnHighlight = self.data('dygraph-showlabelsonhighlight') || true;
+ var gridLineColor = self.data('dygraph-gridlinecolor') || '#EEE';
+ var axisLineColor = self.data('dygraph-axislinecolor') || '#EEE';
+ var maxNumberWidth = self.data('dygraph-maxnumberwidth') || 8;
+ var sigFigs = self.data('dygraph-sigfigs') || null;
+ var digitsAfterDecimal = self.data('dygraph-digitsafterdecimal') || 2;
+ var axisLabelFontSize = self.data('dygraph-axislabelfontsize') || 10;
+ var axisLineWidth = self.data('dygraph-axislinewidth') || 0.3;
+ var drawAxis = self.data('dygraph-drawaxis') || true;
+ var strokeWidth = self.data('dygraph-strokewidth') || 1.0;
+ var drawGapEdgePoints = self.data('dygraph-drawgapedgepoints') || true;
var colors = self.data('dygraph-colors') || NETDATA.colors;
- var pointSize = self.data('dygraph-pointSize') || 1;
- var stepPlot = self.data('dygraph-stepPlot') || false;
- var strokeBorderColor = self.data('dygraph-strokeBorderColor') || 'white';
- var strokeBorderWidth = self.data('dygraph-strokeBorderWidth') || (chart.chart_type == 'stacked')?1.0:0.0;
- var strokePattern = self.data('dygraph-strokePattern') || undefined;
- var highlightCircleSize = self.data('dygraph-highlightCircleSize') || 3;
- var highlightSeriesOpts = self.data('dygraph-highlightSeriesOpts') || { strokeWidth: 1.5 };
- var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightSeriesBackgroundAlpha') || (chart.chart_type == 'stacked')?0.7:0.5;
- var pointClickCallback = self.data('dygraph-pointClickCallback') || undefined;
- var showRangeSelector = self.data('dygraph-showRangeSelector') || false;
- var showRoller = self.data('dygraph-showRoller') || false;
- var valueFormatter = self.data('dygraph-valueFormatter') || undefined; //function(x){ return x.toFixed(2); };
- var rightGap = self.data('dygraph-rightGap') || 5;
- var drawGrid = self.data('dygraph-drawGrid') || true;
- var drawXGrid = self.data('dygraph-drawXGrid') || undefined;
- var drawYGrid = self.data('dygraph-drawYGrid') || undefined;
- var gridLinePattern = self.data('dygraph-gridLinePattern') || null;
- var gridLineWidth = self.data('dygraph-gridLineWidth') || 0.3;
+ var pointSize = self.data('dygraph-pointsize') || 1;
+ var stepPlot = self.data('dygraph-stepplot') || false;
+ var strokeBorderColor = self.data('dygraph-strokebordercolor') || 'white';
+ var strokeBorderWidth = self.data('dygraph-strokeborderwidth') || (chart.chart_type == 'stacked')?1.0:0.0;
+ var strokePattern = self.data('dygraph-strokepattern') || undefined;
+ var highlightCircleSize = self.data('dygraph-highlightcirclesize') || 3;
+ var highlightSeriesOpts = self.data('dygraph-highlightseriesopts') || { strokeWidth: 1.5 };
+ var highlightSeriesBackgroundAlpha = self.data('dygraph-highlightseriesbackgroundalpha') || (chart.chart_type == 'stacked')?0.7:0.5;
+ var pointClickCallback = self.data('dygraph-pointclickcallback') || undefined;
+ var showRangeSelector = self.data('dygraph-showrangeselector') || false;
+ var showRoller = self.data('dygraph-showroller') || false;
+ var valueFormatter = self.data('dygraph-valueformatter') || undefined; //function(x){ return x.toFixed(2); };
+ var rightGap = self.data('dygraph-rightgap') || 5;
+ var drawGrid = self.data('dygraph-drawgrid') || true;
+ var drawXGrid = self.data('dygraph-drawxgrid') || undefined;
+ var drawYGrid = self.data('dygraph-drawygrid') || undefined;
+ var gridLinePattern = self.data('dygraph-gridlinepattern') || null;
+ var gridLineWidth = self.data('dygraph-gridlinewidth') || 0.3;
var options = {
title: title,
showRoller: showRoller,
valueFormatter: valueFormatter,
rightGap: rightGap,
- labels: data.labels,
+ labels: data.result.labels,
axes: {
x: {
pixelsPerLabel: 50,
self.html('<div id="' + uuid + '" style="width: 100%; height: 100%;"></div>');
var dchart = new Dygraph(document.getElementById(uuid),
- data.data, options);
+ data.result.data, options);
self.data('dygraph-instance', dchart)
.data('dygraph-options', options)
var self = $(element);
var morris = self.data('morris-instance');
- if(typeof data.update_every != 'undefined')
- self.data('update-every', data.update_every * 1000);
-
if(morris != null) {
console.log('updating morris');
- morris.setData(data.data);
+ morris.setData(data.result.data);
}
else
console.log('not updating morris');
var uuid = NETDATA.guid();
self.html('<div id="' + uuid + '" style="width: ' + self.data('calculated-width') + 'px; height: ' + self.data('calculated-height') + 'px;"></div>');
- // remove the 'time' element from the labels
- data.labels.splice(0, 1);
-
var options = {
element: uuid,
- data: data.data,
+ data: data.result.data,
xkey: 'time',
- ykeys: data.labels,
- labels: data.labels,
+ ykeys: data.dimension_names,
+ labels: data.dimension_names,
lineWidth: 2,
pointSize: 2,
smooth: true,
morris = new Morris.Area(options);
self.data('morris-instance', morris)
- .data('created', true);
+ .data('created', true);
};
// ----------------------------------------------------------------------------------------------------------------
var gchart = self.data('google-instance');
var options = self.data('google-options');
- if(typeof data.update_every != 'undefined')
- self.data('update-every', data.update_every * 1000);
-
- var datatable = new google.visualization.DataTable(data);
+ var datatable = new google.visualization.DataTable(data.result);
gchart.draw(datatable, options);
};
var self = $(element);
var chart = self.data('chart');
- var datatable = new google.visualization.DataTable(data);
+ var datatable = new google.visualization.DataTable(data.result);
var gchart;
var options = {
initialized: false,
enabled: true,
format: 'json',
- options: 'ms|flip',
+ options: 'ms|flip|jsonwrap',
+ jsonWrapper: true,
pixels_per_point: 2,
detects_dimensions_on_update: false
},
initialized: false,
enabled: true,
format: 'array',
- options: 'flip|min2max',
+ options: 'flip|min2max|jsonwrap',
+ jsonWrapper: true,
pixels_per_point: 2,
detects_dimensions_on_update: false
},
initialized: false,
enabled: true,
format: 'ssvcomma',
- options: 'null2zero|flip|min2max',
+ options: 'null2zero|flip|min2max|jsonwrap',
+ jsonWrapper: true,
pixels_per_point: 2,
detects_dimensions_on_update: false
},
initialized: false,
enabled: true,
format: 'json',
- options: 'objectrows|ms',
+ options: 'objectrows|ms|jsonwrap',
+ jsonWrapper: true,
pixels_per_point: 10,
detects_dimensions_on_update: false
},
initialized: false,
enabled: true,
format: 'datatable',
- options: '',
+ options: 'jsonwrap',
+ jsonWrapper: true,
pixels_per_point: 2,
detects_dimensions_on_update: true
},
enabled: true,
format: 'json',
options: '',
+ jsonWrapper: false,
pixels_per_point: 1,
detects_dimensions_on_update: false
}