diff --git a/applications/airconnect/Makefile b/airconnect/Makefile similarity index 100% rename from applications/airconnect/Makefile rename to airconnect/Makefile diff --git a/applications/airconnect/files/airconnect.config b/airconnect/files/airconnect.config similarity index 100% rename from applications/airconnect/files/airconnect.config rename to airconnect/files/airconnect.config diff --git a/applications/airconnect/files/airconnect.init b/airconnect/files/airconnect.init similarity index 100% rename from applications/airconnect/files/airconnect.init rename to airconnect/files/airconnect.init diff --git a/applications/luci-app-kodexplorer/Makefile b/applications/luci-app-kodexplorer/Makefile deleted file mode 100644 index daa95f6b3..000000000 --- a/applications/luci-app-kodexplorer/Makefile +++ /dev/null @@ -1,18 +0,0 @@ - - -include $(TOPDIR)/rules.mk - -PKG_VERSION:=1.2.1-20230108 -PKG_RELEASE:= - -LUCI_TITLE:=LuCI support for kodexplorer -LUCI_PKGARCH:=all -LUCI_DEPENDS:=+docker +luci-lib-taskd - -define Package/luci-app-kodexplorer/conffiles -/etc/config/kodexplorer -endef - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-kodexplorer/luasrc/controller/kodexplorer.lua b/applications/luci-app-kodexplorer/luasrc/controller/kodexplorer.lua deleted file mode 100755 index a1c618364..000000000 --- a/applications/luci-app-kodexplorer/luasrc/controller/kodexplorer.lua +++ /dev/null @@ -1,7 +0,0 @@ - -module("luci.controller.kodexplorer", package.seeall) - -function index() - entry({"admin", "services", "kodexplorer"}, alias("admin", "services", "kodexplorer", "config"), _("KodExplorer"), 30).dependent = true - entry({"admin", "services", "kodexplorer", "config"}, cbi("kodexplorer")) -end diff --git a/applications/luci-app-kodexplorer/luasrc/view/kodexplorer/status.htm b/applications/luci-app-kodexplorer/luasrc/view/kodexplorer/status.htm deleted file mode 100644 index 0a88625f5..000000000 --- a/applications/luci-app-kodexplorer/luasrc/view/kodexplorer/status.htm +++ /dev/null @@ -1,31 +0,0 @@ -<% -local util = require "luci.util" -local container_status = util.trim(util.exec("/usr/libexec/istorec/kodexplorer.sh status")) -local container_install = (string.len(container_status) > 0) -local container_running = container_status == "running" --%> -
- -
- <% if container_running then %> - - <% else %> - - <% end %> -
-
-<% -if container_running then - local port=util.trim(util.exec("/usr/libexec/istorec/kodexplorer.sh port")) - if port == "" then - port="8081" - end --%> -
- -
- - -
-
-<% end %> \ No newline at end of file diff --git a/applications/luci-app-kodexplorer/po/zh-cn/kodexplorer.po b/applications/luci-app-kodexplorer/po/zh-cn/kodexplorer.po deleted file mode 100644 index 23f4ec7db..000000000 --- a/applications/luci-app-kodexplorer/po/zh-cn/kodexplorer.po +++ /dev/null @@ -1,41 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8" - -msgid "KodExplorer" -msgstr "可道云" - -msgid "Official website:" -msgstr "官方网站:" - -msgid "Private cloud online document management solution based on web technology." -msgstr "基于Web技术的私有云在线文档管理解决方案。" - -msgid "Config path" -msgstr "配置文件路径" - -msgid "Port" -msgstr "端口" - -msgid "Service Status" -msgstr "服务状态" - -msgid "KodExplorer status:" -msgstr "可道云的状态信息如下:" - -msgid "Setup" -msgstr "安装配置" - -msgid "The following parameters will only take effect during installation or upgrade:" -msgstr "以下参数只在安装或者升级时才会生效:" - -msgid "Status" -msgstr "状态" - -msgid "KodExplorer is running" -msgstr "可道云运行中" - -msgid "KodExplorer is not running" -msgstr "可道云未运行" - -msgid "Open KodExplorer" -msgstr "打开可道云" diff --git a/applications/luci-app-kodexplorer/root/etc/config/kodexplorer b/applications/luci-app-kodexplorer/root/etc/config/kodexplorer deleted file mode 100644 index c8f36e049..000000000 --- a/applications/luci-app-kodexplorer/root/etc/config/kodexplorer +++ /dev/null @@ -1,4 +0,0 @@ -config kodexplorer - option 'cache_path' '' - option 'port' '8081' - option 'image_name' 'kodcloud/kodbox:latest' diff --git a/applications/luci-app-kodexplorer/root/usr/share/rpcd/acl.d/luci-app-kodexplorer.json b/applications/luci-app-kodexplorer/root/usr/share/rpcd/acl.d/luci-app-kodexplorer.json deleted file mode 100644 index 96e28b0c8..000000000 --- a/applications/luci-app-kodexplorer/root/usr/share/rpcd/acl.d/luci-app-kodexplorer.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-kodexplorer": { - "description": "Grant UCI access for luci-app-kodexplorer", - "read": { - "uci": [ "kodexplorer" ] - }, - "write": { - "uci": [ "kodexplorer" ] - } - } -} diff --git a/applications/luci-app-netdata/Makefile b/applications/luci-app-netdata/Makefile deleted file mode 100755 index 2666b69b6..000000000 --- a/applications/luci-app-netdata/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2016 Openwrt.org -# Copyright (C) 2020-2021 sirpdboy -# https://github.com/sirpdboy/luci-app-netdata for v 1.30.1 cn -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=LuCI support for Netdata -LUCI_DEPENDS:=+netdata -LUCI_PKGARCH:=all -PKG_VERSION:=1.1-20210610 -PKG_RELEASE:= - -define Build/Compile -endef - - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature - diff --git a/applications/luci-app-netdata/README.md b/applications/luci-app-netdata/README.md deleted file mode 100755 index 06a486b43..000000000 --- a/applications/luci-app-netdata/README.md +++ /dev/null @@ -1,30 +0,0 @@ -luci-app-netdata for OpenWRT/Lede - - -Install to OpenWRT/LEDE - -git clone https://github.com/sirpdboy/luci-app-netdata - -cp -r luci-app-netdata LEDE_DIR/package/luci-app-netdata - -cd LEDE_DIR - -./scripts/feeds update -a - -./scripts/feeds install -a - -make menuconfig - -LuCI ---> - - 1. Collections ---> - - <*> luci - - 3. Applications ---> - - <*> luci-app-netdata.........................LuCI support for Netdata - - -make package/new/luci-app-netdata/compile V=s - diff --git a/applications/luci-app-netdata/luasrc/controller/netdata.lua b/applications/luci-app-netdata/luasrc/controller/netdata.lua deleted file mode 100755 index 29d81e918..000000000 --- a/applications/luci-app-netdata/luasrc/controller/netdata.lua +++ /dev/null @@ -1,12 +0,0 @@ -module("luci.controller.netdata", package.seeall) - -function index() - if not (luci.sys.call("pidof netdata > /dev/null") == 0) then - return - end - local fs = require "nixio.fs" - - entry({"admin","status","netdata"},template("netdata"),_("NetData"),10).leaf=true - - -end \ No newline at end of file diff --git a/applications/luci-app-netdata/luasrc/model/cgi/netdate.lua b/applications/luci-app-netdata/luasrc/model/cgi/netdate.lua deleted file mode 100755 index 134e2bea8..000000000 --- a/applications/luci-app-netdata/luasrc/model/cgi/netdate.lua +++ /dev/null @@ -1,25 +0,0 @@ --- Copyright 2018 Nick Peng (pymumu@gmail.com) - -function index() - - -o = Map("netdate", "" .. translate("实时监控") .."", "" .. translate( "强大的实时监控数据,需要中文版请点击:【升级中文版】") .."") - -t = o:section(TypedSection, "netdate") -t.anonymous = true -t.description = translate(string.format("%s

", status)) - -t:tab("base",translate("Basic Settings")) - -e = t:taboption("base", Button, "restart", translate("手动更新")) -e.inputtitle = translate("升级中文版") -e.inputstyle = "reload" -e.write = function() - luci.sys.call("/usr/share/netdata/netdatacn 2>&1 >/dev/null") - luci.http.redirect(luci.dispatcher.build_url("admin","status","netdata")) -end - -t=o:section(TypedSection,"rss_rules",translate("技术支持")) -t.anonymous = true -t:append(Template("feedback")) -return o diff --git a/applications/luci-app-netdata/luasrc/view/netdata.htm b/applications/luci-app-netdata/luasrc/view/netdata.htm deleted file mode 100755 index 159f8dc28..000000000 --- a/applications/luci-app-netdata/luasrc/view/netdata.htm +++ /dev/null @@ -1,22 +0,0 @@ -<%# - Copyright 2008-2020 sirpdboy Wich - https://github.com/sirpdboy/luci-app-netdata - Licensed to the public under the Apache License 2.0. --%> - -<%+header%> -
-

<%=translate("NetData")%>

- - - -
- -<%+footer%> diff --git a/applications/luci-app-netdata/po/zh-cn/netdata.po b/applications/luci-app-netdata/po/zh-cn/netdata.po deleted file mode 100755 index e8966b815..000000000 --- a/applications/luci-app-netdata/po/zh-cn/netdata.po +++ /dev/null @@ -1,5 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8" - -msgid "NetData" -msgstr "实时监控" diff --git a/applications/luci-app-netdata/readme.txt b/applications/luci-app-netdata/readme.txt deleted file mode 100755 index 72da42502..000000000 --- a/applications/luci-app-netdata/readme.txt +++ /dev/null @@ -1,21 +0,0 @@ -luci-app-netdata for OpenWRT/Lede() - - -Install to OpenWRT/LEDE - -git clone https://github.com/sirpdboy/luci-app-netdata -cp -r luci-app-netdata LEDE_DIR/package/luci-app-netdata - -cd LEDE_DIR -./scripts/feeds update -a -./scripts/feeds install -a - -make menuconfig -LuCI ---> - 1. Collections ---> - <*> luci - 3. Applications ---> - <*> luci-app-netdata.........................LuCI support for Netdata - - -make package/luci-app-netdata/compile V=s \ No newline at end of file diff --git a/applications/luci-app-netdata/root/etc/netdata/apps_groups.conf b/applications/luci-app-netdata/root/etc/netdata/apps_groups.conf deleted file mode 100755 index d326be78f..000000000 --- a/applications/luci-app-netdata/root/etc/netdata/apps_groups.conf +++ /dev/null @@ -1,314 +0,0 @@ -# -# apps.plugin process grouping -# -# The apps.plugin displays charts with information about the processes running. -# This config allows grouping processes together, so that several processes -# will be reported as one. -# -# Only groups in this file are reported. All other processes will be reported -# as 'other'. -# -# For each process given, its whole process tree will be grouped, not just -# the process matched. The plugin will include both parents and childs. -# -# The format is: -# -# group: process1 process2 process3 ... -# -# Each group can be given multiple times, to add more processes to it. -# -# The process names are the ones returned by: -# -# - ps -e or /proc/PID/stat -# - in case of substring mode (see below): /proc/PID/cmdline -# -# To add process names with spaces, enclose them in quotes (single or double) -# example: 'Plex Media Serv' "my other process". -# -# Wildcard support: -# You can add an asterisk (*) at the beginning and/or the end of a process: -# -# *name suffix mode: will search for processes ending with 'name' -# (/proc/PID/stat) -# -# name* prefix mode: will search for processes beginning with 'name' -# (/proc/PID/stat) -# -# *name* substring mode: will search for 'name' in the whole command line -# (/proc/PID/cmdline) -# -# If you enter even just one *name* (substring), apps.plugin will process -# /proc/PID/cmdline for all processes, just once (when they are first seen). -# -# To add processes with single quotes, enclose them in double quotes -# example: "process with this ' single quote" -# -# To add processes with double quotes, enclose them in single quotes: -# example: 'process with this " double quote' -# -# If a group or process name starts with a -, the dimension will be hidden -# (cpu chart only). -# -# If a process starts with a +, debugging will be enabled for it -# (debugging produces a lot of output - do not enable it in production systems) -# -# You can add any number of groups you like. Only the ones found running will -# affect the charts generated. However, producing charts with hundreds of -# dimensions may slow down your web browser. -# -# The order of the entries in this list is important: the first that matches -# a process is used, so put important ones at the top. Processes not matched -# by any row, will inherit it from their parents or children. -# -# The order also controls the order of the dimensions on the generated charts -# (although applications started after apps.plugin is started, will be appended -# to the existing list of dimensions the netdata daemon maintains). - -# ----------------------------------------------------------------------------- -# NETDATA processes accounting - -# netdata main process -netdata: netdata - -# netdata known plugins -# plugins not defined here will be accumulated in netdata, above -apps.plugin: apps.plugin -freeipmi.plugin: freeipmi.plugin -nfacct.plugin: nfacct.plugin -cups.plugin: cups.plugin -xenstat.plugin: xenstat.plugin -perf.plugin: perf.plugin -charts.d.plugin: *charts.d.plugin* -node.d.plugin: *node.d.plugin* -python.d.plugin: *python.d.plugin* -tc-qos-helper: *tc-qos-helper.sh* -fping: fping -ioping: ioping -go.d.plugin: *go.d.plugin* -slabinfo.plugin: slabinfo.plugin -ebpf.plugin: *ebpf.plugin* - -# agent-service-discovery -agent_sd: agent_sd - -# ----------------------------------------------------------------------------- -# authentication/authorization related servers - -auth: radius* openldap* ldap* slapd authelia -fail2ban: fail2ban* - -# ----------------------------------------------------------------------------- -# web/ftp servers - -httpd: apache* httpd nginx* lighttpd hiawatha -proxy: squid* c-icap squidGuard varnish* -php: php* lsphp* -ftpd: proftpd in.tftpd vsftpd -uwsgi: uwsgi -unicorn: *unicorn* -puma: *puma* - -# ----------------------------------------------------------------------------- -# database servers - -sql: mysqld* mariad* postgres* postmaster* oracle_* ora_* sqlservr -nosql: mongod redis* memcached *couchdb* -timedb: prometheus *carbon-cache.py* *carbon-aggregator.py* *graphite/manage.py* *net.opentsdb.tools.TSDMain* influxd* -columndb: clickhouse-server* - -# ----------------------------------------------------------------------------- -# email servers - -email: dovecot imapd pop3d amavis* master zmstat* zmmailboxdmgr qmgr oqmgr saslauthd opendkim clamd freshclam tlsmgr postfwd2 postscreen postfix smtp* lmtp* sendmail - -# ----------------------------------------------------------------------------- -# network, routing, VPN - -ppp: ppp* -vpn: openvpn pptp* cjdroute gvpe tincd -wifi: hostapd wpa_supplicant NetworkManager -routing: ospfd* ospf6d* bgpd bfdd fabricd isisd eigrpd sharpd staticd ripd ripngd pimd pbrd nhrpd ldpd zebra vrrpd vtysh bird* -modem: ModemManager -tor: tor - -# ----------------------------------------------------------------------------- -# high availability and balancers - -camo: *camo* -balancer: ipvs_* haproxy -ha: corosync hs_logd ha_logd stonithd pacemakerd lrmd crmd - -# ----------------------------------------------------------------------------- -# telephony - -pbx: asterisk safe_asterisk *vicidial* -sip: opensips* stund - -# ----------------------------------------------------------------------------- -# chat - -chat: irssi *vines* *prosody* murmurd - -# ----------------------------------------------------------------------------- -# monitoring - -logs: ulogd* syslog* rsyslog* logrotate systemd-journald rotatelogs -nms: snmpd vnstatd smokeping zabbix* monit munin* mon openhpid watchdog tailon nrpe -splunk: splunkd -azure: mdsd *waagent* *omiserver* *omiagent* hv_kvp_daemon hv_vss_daemon *auoms* *omsagent* - -# ----------------------------------------------------------------------------- -# storage, file systems and file servers - -ceph: ceph-* ceph_* radosgw* rbd-* cephfs-* osdmaptool crushtool -samba: smbd nmbd winbindd ctdbd ctdb-* ctdb_* -nfs: rpcbind rpc.* nfs* -zfs: spl_* z_* txg_* zil_* arc_* l2arc* -btrfs: btrfs* -iscsi: iscsid iscsi_eh - -# ----------------------------------------------------------------------------- -# kubernetes - -kubelet: kubelet -kube-dns: kube-dns -kube-proxy: kube-proxy -metrics-server: metrics-server -heapster: heapster - -# ----------------------------------------------------------------------------- -# containers & virtual machines - -containers: lxc* docker* balena* -VMs: vbox* VBox* qemu* - -# ----------------------------------------------------------------------------- -# ssh servers and clients - -ssh: ssh* scp dropbear - -# ----------------------------------------------------------------------------- -# print servers and clients - -print: cups* lpd lpq - -# ----------------------------------------------------------------------------- -# time servers and clients - -time: ntp* systemd-timesyn* chronyd - -# ----------------------------------------------------------------------------- -# dhcp servers and clients - -dhcp: *dhcp* - -# ----------------------------------------------------------------------------- -# name servers and clients - -dns: named unbound nsd pdns_server knotd gdnsd yadifad dnsmasq systemd-resolve* -dnsdist: dnsdist - -# ----------------------------------------------------------------------------- -# installation / compilation / debugging - -build: cc1 cc1plus as gcc* cppcheck ld make cmake automake autoconf autoreconf -build: git gdb valgrind* - -# ----------------------------------------------------------------------------- -# antivirus - -antivirus: clam* *clam imunify360* - -# ----------------------------------------------------------------------------- -# torrent clients - -torrents: *deluge* transmission* *SickBeard* *CouchPotato* *rtorrent* - -# ----------------------------------------------------------------------------- -# backup servers and clients - -backup: rsync lsyncd bacula* borg rclone - -# ----------------------------------------------------------------------------- -# cron - -cron: cron* atd anacron systemd-cron* - -# ----------------------------------------------------------------------------- -# UPS - -ups: upsmon upsd */nut/* - -# ----------------------------------------------------------------------------- -# media players, servers, clients - -media: mplayer vlc xine mediatomb omxplayer* kodi* xbmc* mediacenter eventlircd -media: mpd minidlnad mt-daapd avahi* Plex* jellyfin squeeze* jackett Ombi - -# ----------------------------------------------------------------------------- -# java applications - -hdfsdatanode: *org.apache.hadoop.hdfs.server.datanode.DataNode* -hdfsnamenode: *org.apache.hadoop.hdfs.server.namenode.NameNode* -hdfsjournalnode: *org.apache.hadoop.hdfs.qjournal.server.JournalNode* -hdfszkfc: *org.apache.hadoop.hdfs.tools.DFSZKFailoverController* - -yarnnode: *org.apache.hadoop.yarn.server.nodemanager.NodeManager* -yarnmgr: *org.apache.hadoop.yarn.server.resourcemanager.ResourceManager* -yarnproxy: *org.apache.hadoop.yarn.server.webproxy.WebAppProxyServer* - -sparkworker: *org.apache.spark.deploy.worker.Worker* -sparkmaster: *org.apache.spark.deploy.master.Master* - -hbaseregion: *org.apache.hadoop.hbase.regionserver.HRegionServer* -hbaserest: *org.apache.hadoop.hbase.rest.RESTServer* -hbasethrift: *org.apache.hadoop.hbase.thrift.ThriftServer* -hbasemaster: *org.apache.hadoop.hbase.master.HMaster* - -zookeeper: *org.apache.zookeeper.server.quorum.QuorumPeerMain* - -hive2: *org.apache.hive.service.server.HiveServer2* -hivemetastore: *org.apache.hadoop.hive.metastore.HiveMetaStore* - -solr: *solr.install.dir* - -airflow: *airflow* - -# ----------------------------------------------------------------------------- -# X - -X: X Xorg xinit lightdm xdm pulseaudio gkrellm xfwm4 xfdesktop xfce* Thunar -X: xfsettingsd xfconfd gnome-* gdm gconf* dconf* xfconf* *gvfs gvfs* slim -X: kdeinit* kdm plasmashell -X: evolution-* firefox chromium opera vivaldi-bin epiphany WebKit* -X: '*systemd --user*' chrome *chrome-sandbox* *google-chrome* *chromium* *firefox* - -# ----------------------------------------------------------------------------- -# Kernel / System - -ksmd: ksmd - -system: systemd-* udisks* udevd* *udevd connmand ipv6_addrconf dbus-* rtkit* -system: inetd xinetd mdadm polkitd acpid uuidd packagekitd upowerd colord -system: accounts-daemon rngd haveged - -kernel: kthreadd kauditd lockd khelper kdevtmpfs khungtaskd rpciod -kernel: fsnotify_mark kthrotld deferwq scsi_* - -# ----------------------------------------------------------------------------- -# other application servers - -kafka: *kafka.Kafka* - -rabbitmq: *rabbitmq* - -sidekiq: *sidekiq* -java: java -ipfs: ipfs - -node: node* -factorio: factorio - -p4: p4* - -git-services: gitea gitlab-runner diff --git a/applications/luci-app-netdata/root/etc/netdata/ebpf.conf b/applications/luci-app-netdata/root/etc/netdata/ebpf.conf deleted file mode 100755 index d9b6b9393..000000000 --- a/applications/luci-app-netdata/root/etc/netdata/ebpf.conf +++ /dev/null @@ -1,7 +0,0 @@ -[global] - ebpf load mode = entry - disable apps = no - -[ebpf programs] - process = yes - network viewer = yes diff --git a/applications/luci-app-netdata/root/etc/netdata/exporting.conf b/applications/luci-app-netdata/root/etc/netdata/exporting.conf deleted file mode 100755 index 9c1e7ffb7..000000000 --- a/applications/luci-app-netdata/root/etc/netdata/exporting.conf +++ /dev/null @@ -1,88 +0,0 @@ -[exporting:global] - enabled = no - # send configured labels = yes - # send automatic labels = no - # update every = 10 - -[prometheus:exporter] - # send names instead of ids = yes - # send configured labels = yes - # send automatic labels = no - # send charts matching = * - # send hosts matching = localhost * - # prefix = netdata - -# An example configuration for graphite, json, opentsdb exporting connectors -# [graphite:my_graphite_instance] - # enabled = no - # destination = localhost - # data source = average - # prefix = netdata - # hostname = my_hostname - # update every = 10 - # buffer on failures = 10 - # timeout ms = 20000 - # send names instead of ids = yes - # send charts matching = * - # send hosts matching = localhost * - -# [prometheus_remote_write:my_prometheus_remote_write_instance] - # enabled = no - # destination = localhost - # remote write URL path = /receive - # data source = average - # prefix = netdata - # hostname = my_hostname - # update every = 10 - # buffer on failures = 10 - # timeout ms = 20000 - # send names instead of ids = yes - # send charts matching = * - # send hosts matching = localhost * - -# [kinesis:my_kinesis_instance] - # enabled = no - # destination = us-east-1 - # stream name = netdata - # aws_access_key_id = my_access_key_id - # aws_secret_access_key = my_aws_secret_access_key - # data source = average - # prefix = netdata - # hostname = my_hostname - # update every = 10 - # buffer on failures = 10 - # timeout ms = 20000 - # send names instead of ids = yes - # send charts matching = * - # send hosts matching = localhost * - -# [pubsub:my_pubsub_instance] - # enabled = no - # destination = pubsub.googleapis.com - # credentials file = /etc/netdata/pubsub_credentials.json - # project id = my_project - # topic id = my_topic - # data source = average - # prefix = netdata - # hostname = my_hostname - # update every = 10 - # buffer on failures = 10 - # timeout ms = 20000 - # send names instead of ids = yes - # send charts matching = * - # send hosts matching = localhost * - -# [mongodb:my_mongodb_instance] - # enabled = no - # destination = localhost - # database = my_database - # collection = my_collection - # data source = average - # prefix = netdata - # hostname = my_hostname - # update every = 10 - # buffer on failures = 10 - # timeout ms = 20000 - # send names instead of ids = yes - # send charts matching = * - # send hosts matching = localhost * diff --git a/applications/luci-app-netdata/root/etc/netdata/netdata.conf b/applications/luci-app-netdata/root/etc/netdata/netdata.conf deleted file mode 100755 index 4b0f5a38b..000000000 --- a/applications/luci-app-netdata/root/etc/netdata/netdata.conf +++ /dev/null @@ -1,43 +0,0 @@ - -[global] - update every = 2 - memory deduplication (ksm) = no - debug log = syslog - error log = syslog - access log = none - run as user = root - -[web] - allow connections from = localhost 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.* - allow dashboard from = localhost 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.* - -[plugins] - cgroups = no - apps = no - charts.d = no - fping = no - node.d = no - python.d = no - - -[plugin:proc] - ipc =no - /proc/sysvipc/shm = no - /sys/devices/system/edac/mc = no - /sys/devices/system/node = no - /proc/net/sockstat = no - /proc/net/netstat = no - /proc/net/snmp = no - /proc/net/softnet_stat = no - /proc/net/sctp/snmp = no - /proc/net/ip_vs/stats = no - /proc/net/stat/synproxy = no - /sys/kernel/mm/ksm = no - /dev/mapper = no - -[plugin:proc:/proc/diskstats] - path to /dev/vx/dsk = - path to /dev/disk/by-label = - -[health] - enabled = no diff --git a/applications/luci-app-netdata/root/etc/netdata/stream.conf b/applications/luci-app-netdata/root/etc/netdata/stream.conf deleted file mode 100755 index b5142632d..000000000 --- a/applications/luci-app-netdata/root/etc/netdata/stream.conf +++ /dev/null @@ -1,205 +0,0 @@ -# netdata configuration for aggregating data from remote hosts -# -# API keys authorize a pair of sending-receiving netdata servers. -# Once their communication is authorized, they can exchange metrics for any -# number of hosts. -# -# You can generate API keys, with the linux command: uuidgen - - -# ----------------------------------------------------------------------------- -# 1. ON CHILD NETDATA - THE ONE THAT WILL BE SENDING METRICS - -[stream] - # Enable this on child nodes, to have them send metrics. - enabled = no - - # Where is the receiving netdata? - # A space separated list of: - # - # [PROTOCOL:]HOST[%INTERFACE][:PORT][:SSL] - # - # If many are given, the first available will get the metrics. - # - # PROTOCOL = tcp, udp, or unix (only tcp and unix are supported by parent nodes) - # HOST = an IPv4, IPv6 IP, or a hostname, or a unix domain socket path. - # IPv6 IPs should be given with brackets [ip:address] - # INTERFACE = the network interface to use (only for IPv6) - # PORT = the port number or service name (/etc/services) - # SSL = when this word appear at the end of the destination string - # the Netdata will encrypt the connection with the parent. - # - # This communication is not HTTP (it cannot be proxied by web proxies). - destination = - - # Skip Certificate verification? - # - # The netdata child is configurated to avoid invalid SSL/TLS certificate, - # so certificates that are self-signed or expired will stop the streaming. - # Case the server certificate is not valid, you can enable the use of - # 'bad' certificates setting the next option as 'yes'. - # - #ssl skip certificate verification = yes - - # Certificate Authority Path - # - # OpenSSL has a default directory where the known certificates are stored, - # case it is necessary it is possible to change this rule using the variable - # "CApath" - # - #CApath = /etc/ssl/certs/ - - # Certificate Authority file - # - # When the Netdata parent has certificate, that is not recognized as valid, - # we can add this certificate in the list of known certificates in CApath - # and give for Netdata as argument. - # - #CAfile = /etc/ssl/certs/cert.pem - - # The API_KEY to use (as the sender) - api key = - - # The timeout to connect and send metrics - timeout seconds = 60 - - # If the destination line above does not specify a port, use this - default port = 19999 - - # filter the charts to be streamed - # netdata SIMPLE PATTERN: - # - space separated list of patterns (use \ to include spaces in patterns) - # - use * as wildcard, any number of times within each pattern - # - prefix a pattern with ! for a negative match (ie not stream the charts it matches) - # - the order of patterns is important (left to right) - # To send all except a few, use: !this !that * (ie append a wildcard pattern) - send charts matching = * - - # The buffer to use for sending metrics. - # 1MB is good for 10-20 seconds of data, so increase this if you expect latencies. - # The buffer is flushed on reconnects (this will not prevent gaps at the charts). - buffer size bytes = 1048576 - - # If the connection fails, or it disconnects, - # retry after that many seconds. - reconnect delay seconds = 5 - - # Sync the clock of the charts for that many iterations, when starting. - initial clock resync iterations = 60 - -# ----------------------------------------------------------------------------- -# 2. ON PARENT NETDATA - THE ONE THAT WILL BE RECEIVING METRICS - -# You can have one API key per child, -# or the same API key for all child nodes. -# -# netdata searches for options in this order: -# -# a) parent netdata settings (netdata.conf) -# b) [stream] section (above) -# c) [API_KEY] section (below, settings for the API key) -# d) [MACHINE_GUID] section (below, settings for each machine) -# -# You can combine the above (the more specific setting will be used). - -# API key authentication -# If the key is not listed here, it will not be able to push metrics. - -# [API_KEY] is [YOUR-API-KEY], i.e [11111111-2222-3333-4444-555555555555] -[API_KEY] - # Default settings for this API key - - # You can disable the API key, by setting this to: no - # The default (for unknown API keys) is: no - enabled = no - - # A list of simple patterns matching the IPs of the servers that - # will be pushing metrics using this API key. - # The metrics are received via the API port, so the same IPs - # should also be matched at netdata.conf [web].allow connections from - allow from = * - - # The default history in entries, for all hosts using this API key. - # You can also set it per host below. - # If you don't set it here, the history size of the central netdata - # will be used. - default history = 3600 - - # The default memory mode to be used for all hosts using this API key. - # You can also set it per host below. - # If you don't set it here, the memory mode of netdata.conf will be used. - # Valid modes: - # save save on exit, load on start - # map like swap (continuously syncing to disks - you need SSD) - # ram keep it in RAM, don't touch the disk - # none no database at all (use this on headless proxies) - # dbengine like a traditional database - default memory mode = ram - - # Shall we enable health monitoring for the hosts using this API key? - # 3 possible values: - # yes enable alarms - # no do not enable alarms - # auto enable alarms, only when the sending netdata is connected. For ephemeral child nodes or child system restarts, - # ensure that the netdata process on the child is gracefully stopped, to prevent invalid last_collected alarms - # You can also set it per host, below. - # The default is taken from [health].enabled of netdata.conf - health enabled by default = auto - - # postpone alarms for a short period after the sender is connected - default postpone alarms on connect seconds = 60 - - # need to route metrics differently? set these. - # the defaults are the ones at the [stream] section (above) - #default proxy enabled = yes | no - #default proxy destination = IP:PORT IP:PORT ... - #default proxy api key = API_KEY - #default proxy send charts matching = * - - -# ----------------------------------------------------------------------------- -# 3. PER SENDING HOST SETTINGS, ON PARENT NETDATA -# THIS IS OPTIONAL - YOU DON'T HAVE TO CONFIGURE IT - -# This section exists to give you finer control of the parent settings for each -# child host, when the same API key is used by many netdata child nodes / proxies. -# -# Each netdata has a unique GUID - generated the first time netdata starts. -# You can find it at /var/lib/netdata/registry/netdata.public.unique.id -# (at the child). -# -# The host sending data will have one. If the host is not ephemeral, -# you can give settings for each sending host here. - -[MACHINE_GUID] - # enable this host: yes | no - # When disabled, the parent will not receive metrics for this host. - # THIS IS NOT A SECURITY MECHANISM - AN ATTACKER CAN SET ANY OTHER GUID. - # Use only the API key for security. - enabled = no - - # A list of simple patterns matching the IPs of the servers that - # will be pushing metrics using this MACHINE GUID. - # The metrics are received via the API port, so the same IPs - # should also be matched at netdata.conf [web].allow connections from - # and at stream.conf [API_KEY].allow from - allow from = * - - # The number of entries in the database - history = 3600 - - # The memory mode of the database: save | map | ram | none | dbengine - memory mode = save - - # Health / alarms control: yes | no | auto - health enabled = yes - - # postpone alarms when the sender connects - postpone alarms on connect seconds = 60 - - # need to route metrics differently? - # the defaults are the ones at the [API KEY] section - #proxy enabled = yes | no - #proxy destination = IP:PORT IP:PORT ... - #proxy api key = API_KEY - #proxy send charts matching = * diff --git a/applications/luci-app-netdata/root/etc/uci-defaults/40_luci-app-netdata b/applications/luci-app-netdata/root/etc/uci-defaults/40_luci-app-netdata deleted file mode 100755 index a6e6d8445..000000000 --- a/applications/luci-app-netdata/root/etc/uci-defaults/40_luci-app-netdata +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -[ -f /usr/share/netdata/webcn/dashboard.js ] && mv -f /usr/share/netdata/webcn/dashboard.js /usr/share/netdata/web/dashboard.js -[ -f /usr/share/netdata/webcn/dashboard_info.js ] && mv -f /usr/share/netdata/webcn/dashboard_info.js /usr/share/netdata/web/dashboard_info.js -[ -f /usr/share/netdata/webcn/main.js ] && mv -f /usr/share/netdata/webcn/dashboard.js /usr/share/netdata/web/main.js -[ -f /usr/share/netdata/webcn/index.html ] && mv -f /usr/share/netdata/webcn/index.html /usr/share/netdata/web/index.html - -rm -rf /tmp/luci-modulecache /tmp/luci-indexcache* -exit 0 diff --git a/applications/luci-app-netdata/root/usr/share/netdata/webcn/dashboard.js b/applications/luci-app-netdata/root/usr/share/netdata/webcn/dashboard.js deleted file mode 100755 index f20f35271..000000000 --- a/applications/luci-app-netdata/root/usr/share/netdata/webcn/dashboard.js +++ /dev/null @@ -1,10378 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// DO NOT EDIT: This file is automatically generated from the source files in src/ - -// ---------------------------------------------------------------------------- -// You can set the following variables before loading this script: - -// 'use strict'; - -/*global netdataNoDygraphs *//* boolean, disable dygraph charts - * (default: false) */ -/*global netdataNoSparklines *//* boolean, disable sparkline charts - * (default: false) */ -/*global netdataNoPeitys *//* boolean, disable peity charts - * (default: false) */ -/*global netdataNoGoogleCharts *//* boolean, disable google charts - * (default: false) */ -/*global netdataNoMorris *//* boolean, disable morris charts - * (default: false) */ -/*global netdataNoEasyPieChart *//* boolean, disable easypiechart charts - * (default: false) */ -/*global netdataNoGauge *//* boolean, disable gauge.js charts - * (default: false) */ -/*global netdataNoD3 *//* boolean, disable d3 charts - * (default: false) */ -/*global netdataNoC3 *//* boolean, disable c3 charts - * (default: false) */ -/*global netdataNoD3pie *//* boolean, disable d3pie charts - * (default: false) */ -/*global netdataNoBootstrap *//* boolean, disable bootstrap - disables help too - * (default: false) */ -/*global netdataNoFontAwesome *//* boolean, disable fontawesome (do not load it) - * (default: false) */ -/*global netdataIcons *//* object, overwrite netdata fontawesome icons - * (default: null) */ -/*global netdataDontStart *//* boolean, do not start the thread to process the charts - * (default: false) */ -/*global netdataErrorCallback *//* function, callback to be called when the dashboard encounters an error - * (default: null) */ -/*global netdataRegistry:true *//* boolean, use the netdata registry - * (default: false) */ -/*global netdataNoRegistry *//* boolean, included only for compatibility with existing custom dashboard - * (obsolete - do not use this any more) */ -/*global netdataRegistryCallback *//* function, callback that will be invoked with one param: the URLs from the registry - * (default: null) */ -/*global netdataShowHelp:true *//* boolean, disable charts help - * (default: true) */ -/*global netdataShowAlarms:true *//* boolean, enable alarms checks and notifications - * (default: false) */ -/*global netdataRegistryAfterMs:true *//* ms, delay registry use at started - * (default: 1500) */ -/*global netdataCallback *//* function, callback to be called when netdata is ready to start - * (default: null) - * netdata will be running while this is called - * (call NETDATA.pause to stop it) */ -/*global netdataPrepCallback *//* function, callback to be called before netdata does anything else - * (default: null) */ -/*global netdataServer *//* string, the URL of the netdata server to use - * (default: the URL the page is hosted at) */ -/*global netdataServerStatic *//* string, the URL of the netdata server to use for static files - * (default: netdataServer) */ -/*global netdataSnapshotData *//* object, a netdata snapshot loaded - * (default: null) */ -/*global netdataAlarmsRecipients *//* array, an array of alarm recipients to show notifications for - * (default: null) */ -/*global netdataAlarmsRemember *//* boolen, keep our position in the alarm log at browser local storage - * (default: true) */ -/*global netdataAlarmsActiveCallback *//* function, a hook for the alarm logs - * (default: undefined) */ -/*global netdataAlarmsNotifCallback *//* function, a hook for alarm notifications - * (default: undefined) */ -/*global netdataIntersectionObserver *//* boolean, enable or disable the use of intersection observer - * (default: true) */ -/*global netdataCheckXSS *//* boolean, enable or disable checking for XSS issues - * (default: false) */ - -// ---------------------------------------------------------------------------- -// global namespace - -// Should stay var! -var NETDATA = window.NETDATA || {}; - -(function(window, document, $, undefined) { - -// *** src/dashboard.js/utils.js - -NETDATA.name2id = function (s) { - return s - .replace(/ /g, '_') - .replace(/:/g, '_') - .replace(/\(/g, '_') - .replace(/\)/g, '_') - .replace(/\./g, '_') - .replace(/\//g, '_'); -}; - -NETDATA.encodeURIComponent = function (s) { - if (typeof(s) === 'string') { - return encodeURIComponent(s); - } - - return s; -}; - -/// A heuristic for detecting slow devices. -let isSlowDeviceResult = undefined; -const isSlowDevice = function () { - if (!isSlowDeviceResult) { - return isSlowDeviceResult; - } - - try { - let ua = navigator.userAgent.toLowerCase(); - - let iOS = /ipad|iphone|ipod/.test(ua) && !window.MSStream; - let android = /android/.test(ua) && !window.MSStream; - isSlowDeviceResult = (iOS || android); - } catch (e) { - isSlowDeviceResult = false; - } - - return isSlowDeviceResult; -}; - -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(); -}; - -NETDATA.zeropad = function (x) { - if (x > -10 && x < 10) { - return '0' + x.toString(); - } else { - return x.toString(); - } -}; - -NETDATA.seconds4human = function (seconds, options) { - let defaultOptions = { - now: '现在', - space: ' ', - negative_suffix: '前', - day: '日', - days: '日', - hour: '小时', - hours: '小时', - minute: '分钟', - minutes: '分钟', - second: '秒', - seconds: '秒', - and: '及' - }; - - if (typeof options !== 'object') { - options = defaultOptions; - } else { - for (var x in defaultOptions) { - if (typeof options[x] !== 'string') { - options[x] = defaultOptions[x]; - } - } - } - - if (typeof seconds === 'string') { - seconds = parseInt(seconds, 10); - } - - if (seconds === 0) { - return options.now; - } - - let suffix = ''; - if (seconds < 0) { - seconds = -seconds; - if (options.negative_suffix !== '') { - suffix = options.space + options.negative_suffix; - } - } - - let days = Math.floor(seconds / 86400); - seconds -= (days * 86400); - - let hours = Math.floor(seconds / 3600); - seconds -= (hours * 3600); - - let minutes = Math.floor(seconds / 60); - seconds -= (minutes * 60); - - let strings = []; - - if (days > 1) { - strings.push(days.toString() + options.space + options.days); - } else if (days === 1) { - strings.push(days.toString() + options.space + options.day); - } - - if (hours > 1) { - strings.push(hours.toString() + options.space + options.hours); - } else if (hours === 1) { - strings.push(hours.toString() + options.space + options.hour); - } - - if (minutes > 1) { - strings.push(minutes.toString() + options.space + options.minutes); - } else if (minutes === 1) { - strings.push(minutes.toString() + options.space + options.minute); - } - - if (seconds > 1) { - strings.push(Math.floor(seconds).toString() + options.space + options.seconds); - } else if (seconds === 1) { - strings.push(Math.floor(seconds).toString() + options.space + options.second); - } - - if (strings.length === 1) { - return strings.pop() + suffix; - } - - let last = strings.pop(); - return strings.join(", ") + " " + options.and + " " + last + suffix; -}; - -// ---------------------------------------------------------------------------------------------------------------- -// element data attributes - -NETDATA.dataAttribute = function (element, attribute, def) { - let key = 'data-' + attribute.toString(); - if (element.hasAttribute(key)) { - let data = element.getAttribute(key); - - if (data === 'true') { - return true; - } - if (data === 'false') { - return false; - } - if (data === 'null') { - return null; - } - - // Only convert to a number if it doesn't change the string - if (data === +data + '') { - return +data; - } - - if (/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/.test(data)) { - return JSON.parse(data); - } - - return data; - } else { - return def; - } -}; - -NETDATA.dataAttributeBoolean = function (element, attribute, def) { - let value = NETDATA.dataAttribute(element, attribute, def); - - if (value === true || value === false) // gmosx: Love this :) - { - return value; - } - - if (typeof(value) === 'string') { - if (value === 'yes' || value === 'on') { - return true; - } - - if (value === '' || value === 'no' || value === 'off' || value === 'null') { - return false; - } - - return def; - } - - if (typeof(value) === 'number') { - return value !== 0; - } - - return def; -}; - -// ---------------------------------------------------------------------------------------------------------------- -// fast numbers formatting - -NETDATA.fastNumberFormat = { - formattersFixed: [], - formattersZeroBased: [], - - // this is the fastest and the preferred - getIntlNumberFormat: function (min, max) { - let key = max; - if (min === max) { - if (typeof this.formattersFixed[key] === 'undefined') { - this.formattersFixed[key] = new Intl.NumberFormat(undefined, { - // style: 'decimal', - // minimumIntegerDigits: 1, - // minimumSignificantDigits: 1, - // maximumSignificantDigits: 1, - useGrouping: true, - minimumFractionDigits: min, - maximumFractionDigits: max - }); - } - - return this.formattersFixed[key]; - } else if (min === 0) { - if (typeof this.formattersZeroBased[key] === 'undefined') { - this.formattersZeroBased[key] = new Intl.NumberFormat(undefined, { - // style: 'decimal', - // minimumIntegerDigits: 1, - // minimumSignificantDigits: 1, - // maximumSignificantDigits: 1, - useGrouping: true, - minimumFractionDigits: min, - maximumFractionDigits: max - }); - } - - return this.formattersZeroBased[key]; - } else { - // this is never used - // it is added just for completeness - return new Intl.NumberFormat(undefined, { - // style: 'decimal', - // minimumIntegerDigits: 1, - // minimumSignificantDigits: 1, - // maximumSignificantDigits: 1, - useGrouping: true, - minimumFractionDigits: min, - maximumFractionDigits: max - }); - } - }, - - // this respects locale - getLocaleString: function (min, max) { - let key = max; - if (min === max) { - if (typeof this.formattersFixed[key] === 'undefined') { - this.formattersFixed[key] = { - format: function (value) { - return value.toLocaleString(undefined, { - // style: 'decimal', - // minimumIntegerDigits: 1, - // minimumSignificantDigits: 1, - // maximumSignificantDigits: 1, - useGrouping: true, - minimumFractionDigits: min, - maximumFractionDigits: max - }); - } - }; - } - - return this.formattersFixed[key]; - } else if (min === 0) { - if (typeof this.formattersZeroBased[key] === 'undefined') { - this.formattersZeroBased[key] = { - format: function (value) { - return value.toLocaleString(undefined, { - // style: 'decimal', - // minimumIntegerDigits: 1, - // minimumSignificantDigits: 1, - // maximumSignificantDigits: 1, - useGrouping: true, - minimumFractionDigits: min, - maximumFractionDigits: max - }); - } - }; - } - - return this.formattersZeroBased[key]; - } else { - return { - format: function (value) { - return value.toLocaleString(undefined, { - // style: 'decimal', - // minimumIntegerDigits: 1, - // minimumSignificantDigits: 1, - // maximumSignificantDigits: 1, - useGrouping: true, - minimumFractionDigits: min, - maximumFractionDigits: max - }); - } - }; - } - }, - - // the fallback - getFixed: function (min, max) { - let key = max; - if (min === max) { - if (typeof this.formattersFixed[key] === 'undefined') { - this.formattersFixed[key] = { - format: function (value) { - if (value === 0) { - return "0"; - } - return value.toFixed(max); - } - }; - } - - return this.formattersFixed[key]; - } else if (min === 0) { - if (typeof this.formattersZeroBased[key] === 'undefined') { - this.formattersZeroBased[key] = { - format: function (value) { - if (value === 0) { - return "0"; - } - return value.toFixed(max); - } - }; - } - - return this.formattersZeroBased[key]; - } else { - return { - format: function (value) { - if (value === 0) { - return "0"; - } - return value.toFixed(max); - } - }; - } - }, - - testIntlNumberFormat: function () { - let value = 1.12345; - let e1 = "1.12", e2 = "1,12"; - let s = ""; - - try { - let x = new Intl.NumberFormat(undefined, { - useGrouping: true, - minimumFractionDigits: 2, - maximumFractionDigits: 2 - }); - - s = x.format(value); - } catch (e) { - s = ""; - } - - // console.log('NumberFormat: ', s); - return (s === e1 || s === e2); - }, - - testLocaleString: function () { - let value = 1.12345; - let e1 = "1.12", e2 = "1,12"; - let s = ""; - - try { - s = value.toLocaleString(undefined, { - useGrouping: true, - minimumFractionDigits: 2, - maximumFractionDigits: 2 - }); - } catch (e) { - s = ""; - } - - // console.log('localeString: ', s); - return (s === e1 || s === e2); - }, - - // on first run we decide which formatter to use - get: function (min, max) { - if (this.testIntlNumberFormat()) { - // console.log('numberformat'); - this.get = this.getIntlNumberFormat; - } else if (this.testLocaleString()) { - // console.log('localestring'); - this.get = this.getLocaleString; - } else { - // console.log('fixed'); - this.get = this.getFixed; - } - return this.get(min, max); - } -}; - -// ---------------------------------------------------------------------------------------------------------------- -// Detect the netdata server - -// http://stackoverflow.com/questions/984510/what-is-my-script-src-url -// http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url -NETDATA._scriptSource = function () { - let script = null; - - if (typeof document.currentScript !== 'undefined') { - script = document.currentScript; - } else { - const all_scripts = document.getElementsByTagName('script'); - script = all_scripts[all_scripts.length - 1]; - } - - if (typeof script.getAttribute.length !== 'undefined') { - script = script.src; - } else { - script = script.getAttribute('src', -1); - } - - return script; -}; - -// *** src/dashboard.js/server-detection.js - -if (typeof netdataServer !== 'undefined') { - NETDATA.serverDefault = netdataServer; -} else { - let s = NETDATA._scriptSource(); - if (s) { - NETDATA.serverDefault = s.replace(/\/dashboard.js(\?.*)?$/g, ""); - } else { - console.log('WARNING: Cannot detect the URL of the netdata server.'); - NETDATA.serverDefault = null; - } -} - -if (NETDATA.serverDefault === null) { - NETDATA.serverDefault = ''; -} else if (NETDATA.serverDefault.slice(-1) !== '/') { - NETDATA.serverDefault += '/'; -} - -if (typeof netdataServerStatic !== 'undefined' && netdataServerStatic !== null && netdataServerStatic !== '') { - NETDATA.serverStatic = netdataServerStatic; - if (NETDATA.serverStatic.slice(-1) !== '/') { - NETDATA.serverStatic += '/'; - } -} else { - NETDATA.serverStatic = NETDATA.serverDefault; -} - -// *** src/dashboard.js/dependencies.js - -// default URLs for all the external files we need -// make them RELATIVE so that the whole thing can also be -// installed under a web server -NETDATA.jQuery = NETDATA.serverStatic + 'lib/jquery-2.2.4.min.js'; -NETDATA.peity_js = NETDATA.serverStatic + 'lib/jquery.peity-3.2.0.min.js'; -NETDATA.sparkline_js = NETDATA.serverStatic + 'lib/jquery.sparkline-2.1.2.min.js'; -NETDATA.easypiechart_js = NETDATA.serverStatic + 'lib/jquery.easypiechart-97b5824.min.js'; -NETDATA.gauge_js = NETDATA.serverStatic + 'lib/gauge-1.3.2.min.js'; -NETDATA.dygraph_js = NETDATA.serverStatic + 'lib/dygraph-c91c859.min.js'; -NETDATA.dygraph_smooth_js = NETDATA.serverStatic + 'lib/dygraph-smooth-plotter-c91c859.js'; -// NETDATA.raphael_js = NETDATA.serverStatic + 'lib/raphael-2.2.4-min.js'; -// NETDATA.c3_js = NETDATA.serverStatic + 'lib/c3-0.4.18.min.js'; -// NETDATA.c3_css = NETDATA.serverStatic + 'css/c3-0.4.18.min.css'; -NETDATA.d3pie_js = NETDATA.serverStatic + 'lib/d3pie-0.2.1-netdata-3.js'; -NETDATA.d3_js = NETDATA.serverStatic + 'lib/d3-4.12.2.min.js'; -// NETDATA.morris_js = NETDATA.serverStatic + 'lib/morris-0.5.1.min.js'; -// NETDATA.morris_css = NETDATA.serverStatic + 'css/morris-0.5.1.css'; -NETDATA.google_js = 'https://www.google.com/jsapi'; -// Error Handling - -NETDATA.errorCodes = { - 100: {message: "Cannot load chart library", alert: true}, - 101: {message: "Cannot load jQuery", alert: true}, - 402: {message: "Chart library not found", alert: false}, - 403: {message: "Chart library not enabled/is failed", alert: false}, - 404: {message: "Chart not found", alert: false}, - 405: {message: "Cannot download charts index from server", alert: true}, - 406: {message: "Invalid charts index downloaded from server", alert: true}, - 407: {message: "Cannot HELLO netdata server", alert: false}, - 408: {message: "Netdata servers sent invalid response to HELLO", alert: false}, - 409: {message: "Cannot ACCESS netdata registry", alert: false}, - 410: {message: "Netdata registry ACCESS failed", alert: false}, - 411: {message: "Netdata registry server send invalid response to DELETE ", alert: false}, - 412: {message: "Netdata registry DELETE failed", alert: false}, - 413: {message: "Netdata registry server send invalid response to SWITCH ", alert: false}, - 414: {message: "Netdata registry SWITCH failed", alert: false}, - 415: {message: "Netdata alarms download failed", alert: false}, - 416: {message: "Netdata alarms log download failed", alert: false}, - 417: {message: "Netdata registry server send invalid response to SEARCH ", alert: false}, - 418: {message: "Netdata registry SEARCH failed", alert: false} -}; - -NETDATA.errorLast = { - code: 0, - message: "", - datetime: 0 -}; - -NETDATA.error = function (code, msg) { - NETDATA.errorLast.code = code; - NETDATA.errorLast.message = msg; - NETDATA.errorLast.datetime = Date.now(); - - console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg); - - let ret = true; - if (typeof netdataErrorCallback === 'function') { - ret = netdataErrorCallback('system', code, msg); - } - - if (ret && NETDATA.errorCodes[code].alert) { - alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg); - } -}; - -NETDATA.errorReset = function () { - NETDATA.errorLast.code = 0; - NETDATA.errorLast.message = "You are doing fine!"; - NETDATA.errorLast.datetime = 0; -}; -// *** src/dashboard.js/compatibility.js - -// Compatibility fixes. - -// fix IE issue with console -if (!window.console) { - window.console = { - log: function () { - } - }; -} - -// if string.endsWith is not defined, define it -if (typeof String.prototype.endsWith !== 'function') { - String.prototype.endsWith = function (s) { - if (s.length > this.length) { - return false; - } - return this.slice(-s.length) === s; - }; -} - -// if string.startsWith is not defined, define it -if (typeof String.prototype.startsWith !== 'function') { - String.prototype.startsWith = function (s) { - if (s.length > this.length) { - return false; - } - return this.slice(s.length) === s; - }; -} -// ---------------------------------------------------------------------------------------------------------------- -// XSS checks - -NETDATA.xss = { - enabled: (typeof netdataCheckXSS === 'undefined') ? false : netdataCheckXSS, - enabled_for_data: (typeof netdataCheckXSS === 'undefined') ? false : netdataCheckXSS, - - string: function (s) { - return s.toString() - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - }, - - object: function (name, obj, ignore_regex) { - if (typeof ignore_regex !== 'undefined' && ignore_regex.test(name)) { - // console.log('XSS: ignoring "' + name + '"'); - return obj; - } - - switch (typeof(obj)) { - case 'string': - const ret = this.string(obj); - if (ret !== obj) { - console.log('XSS protection changed string ' + name + ' from "' + obj + '" to "' + ret + '"'); - } - return ret; - - case 'object': - if (obj === null) { - return obj; - } - - if (Array.isArray(obj)) { - // console.log('checking array "' + name + '"'); - - let len = obj.length; - while (len--) { - obj[len] = this.object(name + '[' + len + ']', obj[len], ignore_regex); - } - } else { - // console.log('checking object "' + name + '"'); - - for (var i in obj) { - if (obj.hasOwnProperty(i) === false) { - continue; - } - if (this.string(i) !== i) { - console.log('XSS protection removed invalid object member "' + name + '.' + i + '"'); - delete obj[i]; - } else { - obj[i] = this.object(name + '.' + i, obj[i], ignore_regex); - } - } - } - return obj; - - default: - return obj; - } - }, - - checkOptional: function (name, obj, ignore_regex) { - if (this.enabled) { - //console.log('XSS: checking optional "' + name + '"...'); - return this.object(name, obj, ignore_regex); - } - return obj; - }, - - checkAlways: function (name, obj, ignore_regex) { - //console.log('XSS: checking always "' + name + '"...'); - return this.object(name, obj, ignore_regex); - }, - - checkData: function (name, obj, ignore_regex) { - if (this.enabled_for_data) { - //console.log('XSS: checking data "' + name + '"...'); - return this.object(name, obj, ignore_regex); - } - return obj; - } -}; -NETDATA.colorHex2Rgb = function (hex) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - let shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - hex = hex.replace(shorthandRegex, function (m, r, g, b) { - return r + r + g + g + b + b; - }); - - let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } : null; -}; - -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 - let rgb = "#"; - for (let i = 0; i < 3; i++) { - let 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.unitsConversion = { - keys: {}, // keys for data-common-units - latest: {}, // latest selected units for data-common-units - - globalReset: function () { - this.keys = {}; - this.latest = {}; - }, - - scalableUnits: { - 'packets/s': { - 'pps': 1, - 'Kpps': 1000, - 'Mpps': 1000000 - }, - 'pps': { - 'pps': 1, - 'Kpps': 1000, - 'Mpps': 1000000 - }, - 'kilobits/s': { - 'bits/s': 1 / 1000, - 'kilobits/s': 1, - 'megabits/s': 1000, - 'gigabits/s': 1000000, - 'terabits/s': 1000000000 - }, - 'bytes/s': { - 'bytes/s': 1, - 'kilobytes/s': 1024, - 'megabytes/s': 1024 * 1024, - 'gigabytes/s': 1024 * 1024 * 1024, - 'terabytes/s': 1024 * 1024 * 1024 * 1024 - }, - 'kilobytes/s': { - 'bytes/s': 1 / 1024, - 'kilobytes/s': 1, - 'megabytes/s': 1024, - 'gigabytes/s': 1024 * 1024, - 'terabytes/s': 1024 * 1024 * 1024 - }, - 'B/s': { - 'B/s': 1, - 'KiB/s': 1024, - 'MiB/s': 1024 * 1024, - 'GiB/s': 1024 * 1024 * 1024, - 'TiB/s': 1024 * 1024 * 1024 * 1024 - }, - 'KB/s': { - 'B/s': 1 / 1024, - 'KB/s': 1, - 'MB/s': 1024, - 'GB/s': 1024 * 1024, - 'TB/s': 1024 * 1024 * 1024 - }, - 'KiB/s': { - 'B/s': 1 / 1024, - 'KiB/s': 1, - 'MiB/s': 1024, - 'GiB/s': 1024 * 1024, - 'TiB/s': 1024 * 1024 * 1024 - }, - 'B': { - 'B': 1, - 'KiB': 1024, - 'MiB': 1024 * 1024, - 'GiB': 1024 * 1024 * 1024, - 'TiB': 1024 * 1024 * 1024 * 1024, - 'PiB': 1024 * 1024 * 1024 * 1024 * 1024 - }, - 'KB': { - 'B': 1 / 1024, - 'KB': 1, - 'MB': 1024, - 'GB': 1024 * 1024, - 'TB': 1024 * 1024 * 1024 - }, - 'KiB': { - 'B': 1 / 1024, - 'KiB': 1, - 'MiB': 1024, - 'GiB': 1024 * 1024, - 'TiB': 1024 * 1024 * 1024 - }, - 'MB': { - 'B': 1 / (1024 * 1024), - 'KB': 1 / 1024, - 'MB': 1, - 'GB': 1024, - 'TB': 1024 * 1024, - 'PB': 1024 * 1024 * 1024 - }, - 'MiB': { - 'B': 1 / (1024 * 1024), - 'KiB': 1 / 1024, - 'MiB': 1, - 'GiB': 1024, - 'TiB': 1024 * 1024, - 'PiB': 1024 * 1024 * 1024 - }, - 'GB': { - 'B': 1 / (1024 * 1024 * 1024), - 'KB': 1 / (1024 * 1024), - 'MB': 1 / 1024, - 'GB': 1, - 'TB': 1024, - 'PB': 1024 * 1024, - 'EB': 1024 * 1024 * 1024 - }, - 'GiB': { - 'B': 1 / (1024 * 1024 * 1024), - 'KiB': 1 / (1024 * 1024), - 'MiB': 1 / 1024, - 'GiB': 1, - 'TiB': 1024, - 'PiB': 1024 * 1024, - 'EiB': 1024 * 1024 * 1024 - }, - 'num': { - 'num': 1, - 'num (K)': 1000, - 'num (M)': 1000000, - 'num (G)': 1000000000, - 'num (T)': 1000000000000 - } - /* - 'milliseconds': { - 'seconds': 1000 - }, - 'seconds': { - 'milliseconds': 0.001, - 'seconds': 1, - 'minutes': 60, - 'hours': 3600, - 'days': 86400 - } - */ - }, - - convertibleUnits: { - 'Celsius': { - 'Fahrenheit': { - check: function (max) { - void(max); - return NETDATA.options.current.temperature === 'fahrenheit'; - }, - convert: function (value) { - return value * 9 / 5 + 32; - } - } - }, - 'celsius': { - 'fahrenheit': { - check: function (max) { - void(max); - return NETDATA.options.current.temperature === 'fahrenheit'; - }, - convert: function (value) { - return value * 9 / 5 + 32; - } - } - }, - 'seconds': { - 'time': { - check: function (max) { - void(max); - return NETDATA.options.current.seconds_as_time; - }, - convert: function (seconds) { - return NETDATA.unitsConversion.seconds2time(seconds); - } - } - }, - 'milliseconds': { - 'milliseconds': { - check: function (max) { - return NETDATA.options.current.seconds_as_time && max < 1000; - }, - convert: function (milliseconds) { - let tms = Math.round(milliseconds * 10); - milliseconds = Math.floor(tms / 10); - - tms -= milliseconds * 10; - - return (milliseconds).toString() + '.' + tms.toString(); - } - }, - 'seconds': { - check: function (max) { - return NETDATA.options.current.seconds_as_time && max >= 1000 && max < 60000; - }, - convert: function (milliseconds) { - milliseconds = Math.round(milliseconds); - - let seconds = Math.floor(milliseconds / 1000); - milliseconds -= seconds * 1000; - - milliseconds = Math.round(milliseconds / 10); - - return seconds.toString() + '.' - + NETDATA.zeropad(milliseconds); - } - }, - 'M:SS.ms': { - check: function (max) { - return NETDATA.options.current.seconds_as_time && max >= 60000; - }, - convert: function (milliseconds) { - milliseconds = Math.round(milliseconds); - - let minutes = Math.floor(milliseconds / 60000); - milliseconds -= minutes * 60000; - - let seconds = Math.floor(milliseconds / 1000); - milliseconds -= seconds * 1000; - - milliseconds = Math.round(milliseconds / 10); - - return minutes.toString() + ':' - + NETDATA.zeropad(seconds) + '.' - + NETDATA.zeropad(milliseconds); - } - } - }, - 'nanoseconds': { - 'nanoseconds': { - check: function (max) { - return NETDATA.options.current.seconds_as_time && max < 1000; - }, - convert: function (nanoseconds) { - let tms = Math.round(nanoseconds * 10); - nanoseconds = Math.floor(tms / 10); - - tms -= nanoseconds * 10; - - return (nanoseconds).toString() + '.' + tms.toString(); - } - }, - 'microseconds': { - check: function (max) { - return NETDATA.options.current.seconds_as_time - && max >= 1000 && max < 1000 * 1000; - }, - convert: function (nanoseconds) { - nanoseconds = Math.round(nanoseconds); - - let microseconds = Math.floor(nanoseconds / 1000); - nanoseconds -= microseconds * 1000; - - nanoseconds = Math.round(nanoseconds / 10 ); - - return microseconds.toString() + '.' - + NETDATA.zeropad(nanoseconds); - } - }, - 'milliseconds': { - check: function (max) { - return NETDATA.options.current.seconds_as_time - && max >= 1000 * 1000 && max < 1000 * 1000 * 1000; - }, - convert: function (nanoseconds) { - nanoseconds = Math.round(nanoseconds); - - let milliseconds = Math.floor(nanoseconds / 1000 / 1000); - nanoseconds -= milliseconds * 1000 * 1000; - - nanoseconds = Math.round(nanoseconds / 1000 / 10); - - return milliseconds.toString() + '.' - + NETDATA.zeropad(nanoseconds); - } - }, - 'seconds': { - check: function (max) { - return NETDATA.options.current.seconds_as_time - && max >= 1000 * 1000 * 1000; - }, - convert: function (nanoseconds) { - nanoseconds = Math.round(nanoseconds); - - let seconds = Math.floor(nanoseconds / 1000 / 1000 / 1000); - nanoseconds -= seconds * 1000 * 1000 * 1000; - - nanoseconds = Math.round(nanoseconds / 1000 / 1000 / 10); - - return seconds.toString() + '.' - + NETDATA.zeropad(nanoseconds); - } - }, - } - }, - - seconds2time: function (seconds) { - seconds = Math.abs(seconds); - - let days = Math.floor(seconds / 86400); - seconds -= days * 86400; - - let hours = Math.floor(seconds / 3600); - seconds -= hours * 3600; - - let minutes = Math.floor(seconds / 60); - seconds -= minutes * 60; - - seconds = Math.round(seconds); - - let ms_txt = ''; - /* - let ms = seconds - Math.floor(seconds); - seconds -= ms; - ms = Math.round(ms * 1000); - - if (ms > 1) { - if (ms < 10) - ms_txt = '.00' + ms.toString(); - else if (ms < 100) - ms_txt = '.0' + ms.toString(); - else - ms_txt = '.' + ms.toString(); - } - */ - - return ((days > 0) ? days.toString() + 'd:' : '').toString() - + NETDATA.zeropad(hours) + ':' - + NETDATA.zeropad(minutes) + ':' - + NETDATA.zeropad(seconds) - + ms_txt; - }, - - // get a function that converts the units - // + every time units are switched call the callback - get: function (uuid, min, max, units, desired_units, common_units_name, switch_units_callback) { - // validate the parameters - if (typeof units === 'undefined') { - units = 'undefined'; - } - - // check if we support units conversion - if (typeof this.scalableUnits[units] === 'undefined' && typeof this.convertibleUnits[units] === 'undefined') { - // we can't convert these units - //console.log('DEBUG: ' + uuid.toString() + ' can\'t convert units: ' + units.toString()); - return function (value) { - return value; - }; - } - - // check if the caller wants the original units - if (typeof desired_units === 'undefined' || desired_units === null || desired_units === 'original' || desired_units === units) { - //console.log('DEBUG: ' + uuid.toString() + ' original units wanted'); - switch_units_callback(units); - return function (value) { - return value; - }; - } - - // now we know we can convert the units - // and the caller wants some kind of conversion - - let tunits = null; - let tdivider = 0; - - if (typeof this.scalableUnits[units] !== 'undefined') { - // units that can be scaled - // we decide a divider - - // console.log('NETDATA.unitsConversion.get(' + units.toString() + ', ' + desired_units.toString() + ', function()) decide divider with min = ' + min.toString() + ', max = ' + max.toString()); - - if (desired_units === 'auto') { - // the caller wants to auto-scale the units - - // find the absolute maximum value that is rendered on the chart - // based on this we decide the scale - min = Math.abs(min); - max = Math.abs(max); - if (min > max) { - max = min; - } - - // find the smallest scale that provides integers - // for (x in this.scalableUnits[units]) { - // if (this.scalableUnits[units].hasOwnProperty(x)) { - // let m = this.scalableUnits[units][x]; - // if (m <= max && m > tdivider) { - // tunits = x; - // tdivider = m; - // } - // } - // } - const sunit = this.scalableUnits[units]; - for (var x of Object.keys(sunit)) { - let m = sunit[x]; - if (m <= max && m > tdivider) { - tunits = x; - tdivider = m; - } - } - - if (tunits === null || tdivider <= 0) { - // we couldn't find one - //console.log('DEBUG: ' + uuid.toString() + ' cannot find an auto-scaling candidate for units: ' + units.toString() + ' (max: ' + max.toString() + ')'); - switch_units_callback(units); - return function (value) { - return value; - }; - } - - if (typeof common_units_name === 'string' && typeof uuid === 'string') { - // the caller wants several charts to have the same units - // data-common-units - - let common_units_key = common_units_name + '-' + units; - - // add our divider into the list of keys - let t = this.keys[common_units_key]; - if (typeof t === 'undefined') { - this.keys[common_units_key] = {}; - t = this.keys[common_units_key]; - } - t[uuid] = { - units: tunits, - divider: tdivider - }; - - // find the max divider of all charts - let common_units = t[uuid]; - for (var x in t) { - if (t.hasOwnProperty(x) && t[x].divider > common_units.divider) { - common_units = t[x]; - } - } - - // save our common_max to the latest keys - let latest = this.latest[common_units_key]; - if (typeof latest === 'undefined') { - this.latest[common_units_key] = {}; - latest = this.latest[common_units_key]; - } - latest.units = common_units.units; - latest.divider = common_units.divider; - - tunits = latest.units; - tdivider = latest.divider; - - //console.log('DEBUG: ' + uuid.toString() + ' converted units: ' + units.toString() + ' to units: ' + tunits.toString() + ' with divider ' + tdivider.toString() + ', common-units=' + common_units_name.toString() + ((t[uuid].divider !== tdivider)?' USED COMMON, mine was ' + t[uuid].units:' set common').toString()); - - // apply it to this chart - switch_units_callback(tunits); - return function (value) { - if (tdivider !== latest.divider) { - // another chart switched our common units - // we should switch them too - //console.log('DEBUG: ' + uuid + ' switching units due to a common-units change, from ' + tunits.toString() + ' to ' + latest.units.toString()); - tunits = latest.units; - tdivider = latest.divider; - switch_units_callback(tunits); - } - - return value / tdivider; - }; - } else { - // the caller did not give data-common-units - // this chart auto-scales independently of all others - //console.log('DEBUG: ' + uuid.toString() + ' converted units: ' + units.toString() + ' to units: ' + tunits.toString() + ' with divider ' + tdivider.toString() + ', autonomously'); - - switch_units_callback(tunits); - return function (value) { - return value / tdivider; - }; - } - } else { - // the caller wants specific units - - if (typeof this.scalableUnits[units][desired_units] !== 'undefined') { - // all good, set the new units - tdivider = this.scalableUnits[units][desired_units]; - // console.log('DEBUG: ' + uuid.toString() + ' converted units: ' + units.toString() + ' to units: ' + desired_units.toString() + ' with divider ' + tdivider.toString() + ', by reference'); - switch_units_callback(desired_units); - return function (value) { - return value / tdivider; - }; - } else { - // oops! switch back to original units - console.log('Units conversion from ' + units.toString() + ' to ' + desired_units.toString() + ' is not supported.'); - switch_units_callback(units); - return function (value) { - return value; - }; - } - } - } else if (typeof this.convertibleUnits[units] !== 'undefined') { - // units that can be converted - if (desired_units === 'auto') { - for (var x in this.convertibleUnits[units]) { - if (this.convertibleUnits[units].hasOwnProperty(x)) { - if (this.convertibleUnits[units][x].check(max)) { - //console.log('DEBUG: ' + uuid.toString() + ' converting ' + units.toString() + ' to: ' + x.toString()); - switch_units_callback(x); - return this.convertibleUnits[units][x].convert; - } - } - } - - // none checked ok - //console.log('DEBUG: ' + uuid.toString() + ' no conversion available for ' + units.toString() + ' to: ' + desired_units.toString()); - switch_units_callback(units); - return function (value) { - return value; - }; - } else if (typeof this.convertibleUnits[units][desired_units] !== 'undefined') { - switch_units_callback(desired_units); - return this.convertibleUnits[units][desired_units].convert; - } else { - console.log('Units conversion from ' + units.toString() + ' to ' + desired_units.toString() + ' is not supported.'); - switch_units_callback(units); - return function (value) { - return value; - }; - } - } else { - // hm... did we forget to implement the new type? - console.log(`Unmatched unit conversion method for units ${units.toString()}`); - switch_units_callback(units); - return function (value) { - return value; - }; - } - } -}; - -NETDATA.icons = { - left: '', - reset: '', - right: '', - zoomIn: '', - zoomOut: '', - resize: '', - lineChart: '', - areaChart: '', - noChart: '', - loading: '', - noData: '' -}; - -if (typeof netdataIcons === 'object') { - // for (let icon in NETDATA.icons) { - // if (NETDATA.icons.hasOwnProperty(icon) && typeof(netdataIcons[icon]) === 'string') - // NETDATA.icons[icon] = netdataIcons[icon]; - // } - for (var icon of Object.keys(NETDATA.icons)) { - if (typeof(netdataIcons[icon]) === 'string') { - NETDATA.icons[icon] = netdataIcons[icon] - } - } -} - -if (typeof netdataSnapshotData === 'undefined') { - netdataSnapshotData = null; -} - -if (typeof netdataShowHelp === 'undefined') { - netdataShowHelp = true; -} - -if (typeof netdataShowAlarms === 'undefined') { - netdataShowAlarms = false; -} - -if (typeof netdataRegistryAfterMs !== 'number' || netdataRegistryAfterMs < 0) { - netdataRegistryAfterMs = 0; // 1500; -} - -if (typeof netdataRegistry === 'undefined') { - // backward compatibility - netdataRegistry = (typeof netdataNoRegistry !== 'undefined' && netdataNoRegistry === false); -} - -if (netdataRegistry === false && typeof netdataRegistryCallback === 'function') { - netdataRegistry = true; -} - -// ---------------------------------------------------------------------------------------------------------------- -// the defaults for all charts - -// if the user does not specify any of these, the following will be used - -NETDATA.chartDefaults = { - width: '100%', // the chart width - can be null - height: '100%', // the chart height - can be null - min_width: null, // the chart minimum width - can be null - library: 'dygraph', // the graphing library to use - method: 'average', // the grouping method - before: 0, // panning - after: -600, // panning - pixels_per_point: 1, // the detail of the chart - fill_luminance: 0.8 // luminance of colors in solid areas -}; - -// ---------------------------------------------------------------------------------------------------------------- -// global options - -NETDATA.options = { - pauseCallback: null, // a callback when we are really paused - - pause: false, // when enabled we don't auto-refresh the charts - - targets: [], // an array of all the state objects that are - // currently active (independently of their - // viewport visibility) - - updated_dom: true, // when true, the DOM has been updated with - // new elements we have to check. - - auto_refresher_fast_weight: 0, // this is the current time in ms, spent - // rendering charts continuously. - // used with .current.fast_render_timeframe - - page_is_visible: true, // when true, this page is visible - - auto_refresher_stop_until: 0, // timestamp in ms - used internally, to stop the - // auto-refresher for some time (when a chart is - // performing pan or zoom, we need to stop refreshing - // all other charts, to have the maximum speed for - // rendering the chart that is panned or zoomed). - // Used with .current.global_pan_sync_time - - on_scroll_refresher_stop_until: 0, // timestamp in ms - used to stop evaluating - // charts for some time, after a page scroll - - last_page_resize: Date.now(), // the timestamp of the last resize request - - last_page_scroll: 0, // the timestamp the last time the page was scrolled - - browser_timezone: 'unknown', // timezone detected by javascript - server_timezone: 'unknown', // timezone reported by the server - - force_data_points: 0, // force the number of points to be returned for charts - fake_chart_rendering: false, // when set to true, the dashboard will download data but will not render the charts - - passive_events: null, // true if the browser supports passive events - - // the current profile - // we may have many... - current: { - units: 'auto', // can be 'auto' or 'original' - temperature: 'celsius', // can be 'celsius' or 'fahrenheit' - seconds_as_time: true, // show seconds as DDd:HH:MM:SS ? - timezone: 'default', // the timezone to use, or 'default' - user_set_server_timezone: 'default', // as set by the user on the dashboard - - legend_toolbox: true, // show the legend toolbox on charts - resize_charts: true, // show the resize handler on charts - - pixels_per_point: isSlowDevice() ? 5 : 1, // the minimum pixels per point for all charts - // increase this to speed javascript up - // each chart library has its own limit too - // the max of this and the chart library is used - // the final is calculated every time, so a change - // here will have immediate effect on the next chart - // update - - idle_between_charts: 100, // ms - how much time to wait between chart updates - - fast_render_timeframe: 200, // ms - render continuously until this time of continuous - // rendering has been reached - // this setting is used to make it render e.g. 10 - // charts at once, sleep idle_between_charts time - // and continue for another 10 charts. - - idle_between_loops: 500, // ms - if all charts have been updated, wait this - // time before starting again. - - idle_parallel_loops: 100, // ms - the time between parallel refresher updates - - idle_lost_focus: 500, // ms - when the window does not have focus, check - // if focus has been regained, every this time - - global_pan_sync_time: 300, // ms - when you pan or zoom a chart, the background - // auto-refreshing of charts is paused for this amount - // of time - - sync_selection_delay: 400, // ms - when you pan or zoom a chart, wait this amount - // of time before setting up synchronized selections - // on hover. - - sync_selection: true, // enable or disable selection sync - - pan_and_zoom_delay: 50, // when panning or zooming, how ofter to update the chart - - sync_pan_and_zoom: true, // enable or disable pan and zoom sync - - pan_and_zoom_data_padding: true, // fetch more data for the master chart when panning or zooming - - update_only_visible: true, // enable or disable visibility management / used for printing - - parallel_refresher: !isSlowDevice(), // enable parallel refresh of charts - - concurrent_refreshes: true, // when parallel_refresher is enabled, sync also the charts - - destroy_on_hide: isSlowDevice(), // destroy charts when they are not visible - - show_help: netdataShowHelp, // when enabled the charts will show some help - show_help_delay_show_ms: 500, - show_help_delay_hide_ms: 0, - - eliminate_zero_dimensions: true, // do not show dimensions with just zeros - - stop_updates_when_focus_is_lost: true, // boolean - shall we stop auto-refreshes when document does not have user focus - stop_updates_while_resizing: 1000, // ms - time to stop auto-refreshes while resizing the charts - - double_click_speed: 500, // ms - time between clicks / taps to detect double click/tap - - smooth_plot: !isSlowDevice(), // enable smooth plot, where possible - - color_fill_opacity_line: 1.0, - color_fill_opacity_area: 0.2, - color_fill_opacity_stacked: 0.8, - - pan_and_zoom_factor: 0.25, // the increment when panning and zooming with the toolbox - pan_and_zoom_factor_multiplier_control: 2.0, - pan_and_zoom_factor_multiplier_shift: 3.0, - pan_and_zoom_factor_multiplier_alt: 4.0, - - abort_ajax_on_scroll: false, // kill pending ajax page scroll - async_on_scroll: false, // sync/async onscroll handler - onscroll_worker_duration_threshold: 30, // time in ms, for async scroll handler - - retries_on_data_failures: 3, // how many retries to make if we can't fetch chart data from the server - - setOptionCallback: function () { - } - }, - - debug: { - show_boxes: false, - main_loop: false, - focus: false, - visibility: false, - chart_data_url: false, - chart_errors: true, // remember to set it to false before merging - chart_timing: false, - chart_calls: false, - libraries: false, - dygraph: false, - globalSelectionSync: false, - globalPanAndZoom: false - } -}; - -NETDATA.statistics = { - refreshes_total: 0, - refreshes_active: 0, - refreshes_active_max: 0 -}; - -// local storage options - -NETDATA.localStorage = { - default: {}, - current: {}, - callback: {} // only used for resetting back to defaults -}; - -NETDATA.localStorageTested = -1; -NETDATA.localStorageTest = function () { - if (NETDATA.localStorageTested !== -1) { - return NETDATA.localStorageTested; - } - - if (typeof Storage !== "undefined" && typeof localStorage === 'object') { - let test = 'test'; - try { - localStorage.setItem(test, test); - localStorage.removeItem(test); - NETDATA.localStorageTested = true; - } catch (e) { - NETDATA.localStorageTested = false; - } - } else { - NETDATA.localStorageTested = false; - } - - return NETDATA.localStorageTested; -}; - -NETDATA.localStorageGet = function (key, def, callback) { - let ret = def; - - if (typeof NETDATA.localStorage.default[key.toString()] === 'undefined') { - NETDATA.localStorage.default[key.toString()] = def; - NETDATA.localStorage.callback[key.toString()] = callback; - } - - if (NETDATA.localStorageTest()) { - try { - // console.log('localStorage: loading "' + key.toString() + '"'); - ret = localStorage.getItem(key.toString()); - // console.log('netdata loaded: ' + key.toString() + ' = ' + ret.toString()); - if (ret === null || ret === 'undefined') { - // console.log('localStorage: cannot load it, saving "' + key.toString() + '" with value "' + JSON.stringify(def) + '"'); - localStorage.setItem(key.toString(), JSON.stringify(def)); - ret = def; - } else { - // console.log('localStorage: got "' + key.toString() + '" with value "' + ret + '"'); - ret = JSON.parse(ret); - // console.log('localStorage: loaded "' + key.toString() + '" as value ' + ret + ' of type ' + typeof(ret)); - } - } catch (error) { - console.log('localStorage: failed to read "' + key.toString() + '", using default: "' + def.toString() + '"'); - ret = def; - } - } - - if (typeof ret === 'undefined' || ret === 'undefined') { - console.log('localStorage: LOADED UNDEFINED "' + key.toString() + '" as value ' + ret + ' of type ' + typeof(ret)); - ret = def; - } - - NETDATA.localStorage.current[key.toString()] = ret; - return ret; -}; - -NETDATA.localStorageSet = function (key, value, callback) { - if (typeof value === 'undefined' || value === 'undefined') { - console.log('localStorage: ATTEMPT TO SET UNDEFINED "' + key.toString() + '" as value ' + value + ' of type ' + typeof(value)); - } - - if (typeof NETDATA.localStorage.default[key.toString()] === 'undefined') { - NETDATA.localStorage.default[key.toString()] = value; - NETDATA.localStorage.current[key.toString()] = value; - NETDATA.localStorage.callback[key.toString()] = callback; - } - - if (NETDATA.localStorageTest()) { - // console.log('localStorage: saving "' + key.toString() + '" with value "' + JSON.stringify(value) + '"'); - try { - localStorage.setItem(key.toString(), JSON.stringify(value)); - } catch (e) { - console.log('localStorage: failed to save "' + key.toString() + '" with value: "' + value.toString() + '"'); - } - } - - NETDATA.localStorage.current[key.toString()] = value; - return value; -}; - -NETDATA.localStorageGetRecursive = function (obj, prefix, callback) { - let keys = Object.keys(obj); - let len = keys.length; - while (len--) { - let i = keys[len]; - - if (typeof obj[i] === 'object') { - //console.log('object ' + prefix + '.' + i.toString()); - NETDATA.localStorageGetRecursive(obj[i], prefix + '.' + i.toString(), callback); - continue; - } - - obj[i] = NETDATA.localStorageGet(prefix + '.' + i.toString(), obj[i], callback); - } -}; - -NETDATA.setOption = function (key, value) { - if (key.toString() === 'setOptionCallback') { - if (typeof NETDATA.options.current.setOptionCallback === 'function') { - NETDATA.options.current[key.toString()] = value; - NETDATA.options.current.setOptionCallback(); - } - } else if (NETDATA.options.current[key.toString()] !== value) { - let name = 'options.' + key.toString(); - - if (typeof NETDATA.localStorage.default[name.toString()] === 'undefined') { - console.log('localStorage: setOption() on unsaved option: "' + name.toString() + '", value: ' + value); - } - - //console.log(NETDATA.localStorage); - //console.log('setOption: setting "' + key.toString() + '" to "' + value + '" of type ' + typeof(value) + ' original type ' + typeof(NETDATA.options.current[key.toString()])); - //console.log(NETDATA.options); - NETDATA.options.current[key.toString()] = NETDATA.localStorageSet(name.toString(), value, null); - - if (typeof NETDATA.options.current.setOptionCallback === 'function') { - NETDATA.options.current.setOptionCallback(); - } - } - - return true; -}; - -NETDATA.getOption = function (key) { - return NETDATA.options.current[key.toString()]; -}; - -// read settings from local storage -NETDATA.localStorageGetRecursive(NETDATA.options.current, 'options', null); - -// always start with this option enabled. -NETDATA.setOption('stop_updates_when_focus_is_lost', true); - -NETDATA.resetOptions = function () { - let keys = Object.keys(NETDATA.localStorage.default); - let len = keys.length; - - while (len--) { - let i = keys[len]; - let a = i.split('.'); - - if (a[0] === 'options') { - if (a[1] === 'setOptionCallback') { - continue; - } - if (typeof NETDATA.localStorage.default[i] === 'undefined') { - continue; - } - if (NETDATA.options.current[i] === NETDATA.localStorage.default[i]) { - continue; - } - - NETDATA.setOption(a[1], NETDATA.localStorage.default[i]); - } else if (a[0] === 'chart_heights') { - if (typeof NETDATA.localStorage.callback[i] === 'function' && typeof NETDATA.localStorage.default[i] !== 'undefined') { - NETDATA.localStorage.callback[i](NETDATA.localStorage.default[i]); - } - } - } - - NETDATA.dateTime.init(NETDATA.options.current.timezone); -}; - -// *** src/dashboard.js/timeout.js - -// TODO: Better name needed - -NETDATA.timeout = { - // by default, these are just wrappers to setTimeout() / clearTimeout() - - step: function (callback) { - return window.setTimeout(callback, 1000 / 60); - }, - - set: function (callback, delay) { - return window.setTimeout(callback, delay); - }, - - clear: function (id) { - return window.clearTimeout(id); - }, - - init: function () { - let custom = true; - - if (window.requestAnimationFrame) { - this.step = function (callback) { - return window.requestAnimationFrame(callback); - }; - - this.clear = function (handle) { - return window.cancelAnimationFrame(handle.value); - }; - // } else if (window.webkitRequestAnimationFrame) { - // this.step = function (callback) { - // return window.webkitRequestAnimationFrame(callback); - // }; - - // if (window.webkitCancelAnimationFrame) { - // this.clear = function (handle) { - // return window.webkitCancelAnimationFrame(handle.value); - // }; - // } else if (window.webkitCancelRequestAnimationFrame) { - // this.clear = function (handle) { - // return window.webkitCancelRequestAnimationFrame(handle.value); - // }; - // } - // } else if (window.mozRequestAnimationFrame) { - // this.step = function (callback) { - // return window.mozRequestAnimationFrame(callback); - // }; - - // this.clear = function (handle) { - // return window.mozCancelRequestAnimationFrame(handle.value); - // }; - // } else if (window.oRequestAnimationFrame) { - // this.step = function (callback) { - // return window.oRequestAnimationFrame(callback); - // }; - - // this.clear = function (handle) { - // return window.oCancelRequestAnimationFrame(handle.value); - // }; - // } else if (window.msRequestAnimationFrame) { - // this.step = function (callback) { - // return window.msRequestAnimationFrame(callback); - // }; - - // this.clear = function (handle) { - // return window.msCancelRequestAnimationFrame(handle.value); - // }; - } else { - custom = false; - } - - if (custom) { - // we have installed custom .step() / .clear() functions - // overwrite the .set() too - - this.set = function (callback, delay) { - let start = Date.now(), - handle = new Object(); - - const loop = () => { - let current = Date.now(), - delta = current - start; - - if (delta >= delay) { - callback.call(); - } else { - handle.value = this.step(loop); - } - } - - handle.value = this.step(loop); - return handle; - }; - } - } -}; - -NETDATA.timeout.init(); -// Codacy declarations -/* global netdataTheme */ - -NETDATA.themes = { - white: { - bootstrap_css: NETDATA.serverStatic + 'css/bootstrap-3.3.7.css', - dashboard_css: NETDATA.serverStatic + 'dashboard.css?v20190902-0', - background: '#FFFFFF', - foreground: '#000000', - grid: '#F0F0F0', - axis: '#F0F0F0', - highlight: '#F5F5F5', - colors: ['#3366CC', '#DC3912', '#109618', '#FF9900', '#990099', '#DD4477', - '#3B3EAC', '#66AA00', '#0099C6', '#B82E2E', '#AAAA11', '#5574A6', - '#994499', '#22AA99', '#6633CC', '#E67300', '#316395', '#8B0707', - '#329262', '#3B3EAC'], - easypiechart_track: '#f0f0f0', - easypiechart_scale: '#dfe0e0', - gauge_pointer: '#C0C0C0', - gauge_stroke: '#F0F0F0', - gauge_gradient: false, - d3pie: { - title: '#333333', - subtitle: '#666666', - footer: '#888888', - other: '#aaaaaa', - mainlabel: '#333333', - percentage: '#dddddd', - value: '#aaaa22', - tooltip_bg: '#000000', - tooltip_fg: '#efefef', - segment_stroke: "#ffffff", - gradient_color: '#000000' - } - }, - slate: { - bootstrap_css: NETDATA.serverStatic + 'css/bootstrap-slate-flat-3.3.7.css?v20161229-1', - dashboard_css: NETDATA.serverStatic + 'dashboard.slate.css?v20190902-0', - background: '#272b30', - foreground: '#C8C8C8', - grid: '#283236', - axis: '#283236', - highlight: '#383838', - /* colors: [ '#55bb33', '#ff2222', '#0099C6', '#faa11b', '#adbce0', '#DDDD00', - '#4178ba', '#f58122', '#a5cc39', '#f58667', '#f5ef89', '#cf93c0', - '#a5d18a', '#b8539d', '#3954a3', '#c8a9cf', '#c7de8a', '#fad20a', - '#a6a479', '#a66da8' ], - */ - colors: ['#66AA00', '#FE3912', '#3366CC', '#D66300', '#0099C6', '#DDDD00', - '#5054e6', '#EE9911', '#BB44CC', '#e45757', '#ef0aef', '#CC7700', - '#22AA99', '#109618', '#905bfd', '#f54882', '#4381bf', '#ff3737', - '#329262', '#3B3EFF'], - easypiechart_track: '#373b40', - easypiechart_scale: '#373b40', - gauge_pointer: '#474b50', - gauge_stroke: '#373b40', - gauge_gradient: false, - d3pie: { - title: '#C8C8C8', - subtitle: '#283236', - footer: '#283236', - other: '#283236', - mainlabel: '#C8C8C8', - percentage: '#dddddd', - value: '#cccc44', - tooltip_bg: '#272b30', - tooltip_fg: '#C8C8C8', - segment_stroke: "#283236", - gradient_color: '#000000' - } - } -}; - -if (typeof netdataTheme !== 'undefined' && typeof NETDATA.themes[netdataTheme] !== 'undefined') { - NETDATA.themes.current = NETDATA.themes[netdataTheme]; -} else { - NETDATA.themes.current = NETDATA.themes.white; -} - -NETDATA.colors = NETDATA.themes.current.colors; - -// these are the colors Google Charts are using -// we have them here to attempt emulate their look and feel on the other chart libraries -// http://there4.io/2012/05/02/google-chart-color-list/ -//NETDATA.colors = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6', -// '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11', -// '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6', '#3B3EAC' ]; - -// an alternative set -// http://www.mulinblog.com/a-color-palette-optimized-for-data-visualization/ -// (blue) (red) (orange) (green) (pink) (brown) (purple) (yellow) (gray) -//NETDATA.colors = [ '#5DA5DA', '#F15854', '#FAA43A', '#60BD68', '#F17CB0', '#B2912F', '#B276B2', '#DECF3F', '#4D4D4D' ]; -// dygraph - -// Codacy declarations -/* global smoothPlotter */ -/* global Dygraph */ - -NETDATA.dygraph = { - smooth: false -}; - -NETDATA.dygraphToolboxPanAndZoom = function (state, after, before) { - if (after < state.netdata_first) { - after = state.netdata_first; - } - - if (before > state.netdata_last) { - before = state.netdata_last; - } - - state.setMode('zoom'); - NETDATA.globalSelectionSync.stop(); - NETDATA.globalSelectionSync.delay(); - state.tmp.dygraph_user_action = true; - state.tmp.dygraph_force_zoom = true; - // state.log('toolboxPanAndZoom'); - state.updateChartPanOrZoom(after, before); - NETDATA.globalPanAndZoom.setMaster(state, after, before); -}; - -NETDATA.dygraphSetSelection = function (state, t) { - if (typeof state.tmp.dygraph_instance !== 'undefined') { - let r = state.calculateRowForTime(t); - if (r !== -1) { - state.tmp.dygraph_instance.setSelection(r); - return true; - } else { - state.tmp.dygraph_instance.clearSelection(); - state.legendShowUndefined(); - } - } - - return false; -}; - -NETDATA.dygraphClearSelection = function (state) { - if (typeof state.tmp.dygraph_instance !== 'undefined') { - state.tmp.dygraph_instance.clearSelection(); - } - return true; -}; - -NETDATA.dygraphSmoothInitialize = function (callback) { - $.ajax({ - url: NETDATA.dygraph_smooth_js, - cache: true, - dataType: "script", - xhrFields: {withCredentials: true} // required for the cookie - }) - .done(function () { - NETDATA.dygraph.smooth = true; - smoothPlotter.smoothing = 0.3; - }) - .fail(function () { - NETDATA.dygraph.smooth = false; - }) - .always(function () { - if (typeof callback === "function") { - return callback(); - } - }); -}; - -NETDATA.dygraphInitialize = function (callback) { - if (typeof netdataNoDygraphs === 'undefined' || !netdataNoDygraphs) { - $.ajax({ - url: NETDATA.dygraph_js, - cache: true, - dataType: "script", - xhrFields: {withCredentials: true} // required for the cookie - }) - .done(function () { - NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js); - }) - .fail(function () { - NETDATA.chartLibraries.dygraph.enabled = false; - NETDATA.error(100, NETDATA.dygraph_js); - }) - .always(function () { - if (NETDATA.chartLibraries.dygraph.enabled && NETDATA.options.current.smooth_plot) { - NETDATA.dygraphSmoothInitialize(callback); - } else if (typeof callback === "function") { - return callback(); - } - }); - } else { - NETDATA.chartLibraries.dygraph.enabled = false; - if (typeof callback === "function") { - return callback(); - } - } -}; - -NETDATA.dygraphChartUpdate = function (state, data) { - let dygraph = state.tmp.dygraph_instance; - - if (typeof dygraph === 'undefined') { - return NETDATA.dygraphChartCreate(state, data); - } - - // when the chart is not visible, and hidden - // if there is a window resize, dygraph detects - // its element size as 0x0. - // this will make it re-appear properly - - if (state.tm.last_unhidden > state.tmp.dygraph_last_rendered) { - dygraph.resize(); - } - - let options = { - file: data.result.data, - colors: state.chartColors(), - labels: data.result.labels, - //labelsDivWidth: state.chartWidth() - 70, - includeZero: state.tmp.dygraph_include_zero, - visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names) - }; - - if (state.tmp.dygraph_chart_type === 'stacked') { - if (options.includeZero && state.dimensions_visibility.countSelected() < options.visibility.length) { - options.includeZero = 0; - } - } - - if (!NETDATA.chartLibraries.dygraph.isSparkline(state)) { - options.ylabel = state.units_current; // (state.units_desired === 'auto')?"":state.units_current; - } - - if (state.tmp.dygraph_force_zoom) { - if (NETDATA.options.debug.dygraph || state.debug) { - state.log('dygraphChartUpdate() forced zoom update'); - } - - options.dateWindow = (state.requested_padding !== null) ? [state.view_after, state.view_before] : null; - //options.isZoomedIgnoreProgrammaticZoom = true; - state.tmp.dygraph_force_zoom = false; - } else if (state.current.name !== 'auto') { - if (NETDATA.options.debug.dygraph || state.debug) { - state.log('dygraphChartUpdate() loose update'); - } - } else { - if (NETDATA.options.debug.dygraph || state.debug) { - state.log('dygraphChartUpdate() strict update'); - } - - options.dateWindow = (state.requested_padding !== null) ? [state.view_after, state.view_before] : null; - //options.isZoomedIgnoreProgrammaticZoom = true; - } - - options.valueRange = state.tmp.dygraph_options.valueRange; - - let oldMax = null, oldMin = null; - if (state.tmp.__commonMin !== null) { - state.data.min = state.tmp.dygraph_instance.axes_[0].extremeRange[0]; - oldMin = options.valueRange[0] = NETDATA.commonMin.get(state); - } - if (state.tmp.__commonMax !== null) { - state.data.max = state.tmp.dygraph_instance.axes_[0].extremeRange[1]; - oldMax = options.valueRange[1] = NETDATA.commonMax.get(state); - } - - if (state.tmp.dygraph_smooth_eligible) { - if ((NETDATA.options.current.smooth_plot && state.tmp.dygraph_options.plotter !== smoothPlotter) - || (NETDATA.options.current.smooth_plot === false && state.tmp.dygraph_options.plotter === smoothPlotter)) { - NETDATA.dygraphChartCreate(state, data); - return; - } - } - - if (netdataSnapshotData !== null && NETDATA.globalPanAndZoom.isActive() && NETDATA.globalPanAndZoom.isMaster(state) === false) { - // pan and zoom on snapshots - options.dateWindow = [NETDATA.globalPanAndZoom.force_after_ms, NETDATA.globalPanAndZoom.force_before_ms]; - //options.isZoomedIgnoreProgrammaticZoom = true; - } - - if (NETDATA.chartLibraries.dygraph.isLogScale(state)) { - if (Array.isArray(options.valueRange) && options.valueRange[0] <= 0) { - options.valueRange[0] = null; - } - } - - dygraph.updateOptions(options); - - let redraw = false; - if (oldMin !== null && oldMin > state.tmp.dygraph_instance.axes_[0].extremeRange[0]) { - state.data.min = state.tmp.dygraph_instance.axes_[0].extremeRange[0]; - options.valueRange[0] = NETDATA.commonMin.get(state); - redraw = true; - } - if (oldMax !== null && oldMax < state.tmp.dygraph_instance.axes_[0].extremeRange[1]) { - state.data.max = state.tmp.dygraph_instance.axes_[0].extremeRange[1]; - options.valueRange[1] = NETDATA.commonMax.get(state); - redraw = true; - } - - if (redraw) { - // state.log('forcing redraw to adapt to common- min/max'); - dygraph.updateOptions(options); - } - - state.tmp.dygraph_last_rendered = Date.now(); - return true; -}; - -NETDATA.dygraphChartCreate = function (state, data) { - if (NETDATA.options.debug.dygraph || state.debug) { - state.log('dygraphChartCreate()'); - } - - state.tmp.dygraph_chart_type = NETDATA.dataAttribute(state.element, 'dygraph-type', state.chart.chart_type); - if (state.tmp.dygraph_chart_type === 'stacked' && data.dimensions === 1) { - state.tmp.dygraph_chart_type = 'area'; - } - if (state.tmp.dygraph_chart_type === 'stacked' && NETDATA.chartLibraries.dygraph.isLogScale(state)) { - state.tmp.dygraph_chart_type = 'area'; - } - - let highlightCircleSize = NETDATA.chartLibraries.dygraph.isSparkline(state) ? 3 : 4; - - let smooth = NETDATA.dygraph.smooth - ? (NETDATA.dataAttributeBoolean(state.element, 'dygraph-smooth', (state.tmp.dygraph_chart_type === 'line' && NETDATA.chartLibraries.dygraph.isSparkline(state) === false))) - : false; - - state.tmp.dygraph_include_zero = NETDATA.dataAttribute(state.element, 'dygraph-includezero', (state.tmp.dygraph_chart_type === 'stacked')); - let drawAxis = NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawaxis', true); - - state.tmp.dygraph_options = { - colors: NETDATA.dataAttribute(state.element, 'dygraph-colors', state.chartColors()), - - // leave a few pixels empty on the right of the chart - rightGap: NETDATA.dataAttribute(state.element, 'dygraph-rightgap', 5), - showRangeSelector: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showrangeselector', false), - showRoller: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showroller', false), - title: NETDATA.dataAttribute(state.element, 'dygraph-title', state.title), - titleHeight: NETDATA.dataAttribute(state.element, 'dygraph-titleheight', 19), - legend: NETDATA.dataAttribute(state.element, 'dygraph-legend', 'always'), // we need this to get selection events - labels: data.result.labels, - labelsDiv: NETDATA.dataAttribute(state.element, 'dygraph-labelsdiv', state.element_legend_childs.hidden), - //labelsDivStyles: NETDATA.dataAttribute(state.element, 'dygraph-labelsdivstyles', { 'fontSize':'1px' }), - //labelsDivWidth: NETDATA.dataAttribute(state.element, 'dygraph-labelsdivwidth', state.chartWidth() - 70), - labelsSeparateLines: NETDATA.dataAttributeBoolean(state.element, 'dygraph-labelsseparatelines', true), - labelsShowZeroValues: NETDATA.chartLibraries.dygraph.isLogScale(state) ? false : NETDATA.dataAttributeBoolean(state.element, 'dygraph-labelsshowzerovalues', true), - labelsKMB: false, - labelsKMG2: false, - showLabelsOnHighlight: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showlabelsonhighlight', true), - hideOverlayOnMouseOut: NETDATA.dataAttributeBoolean(state.element, 'dygraph-hideoverlayonmouseout', true), - includeZero: state.tmp.dygraph_include_zero, - xRangePad: NETDATA.dataAttribute(state.element, 'dygraph-xrangepad', 0), - yRangePad: NETDATA.dataAttribute(state.element, 'dygraph-yrangepad', 1), - valueRange: NETDATA.dataAttribute(state.element, 'dygraph-valuerange', [null, null]), - ylabel: state.units_current, // (state.units_desired === 'auto')?"":state.units_current, - yLabelWidth: NETDATA.dataAttribute(state.element, 'dygraph-ylabelwidth', 12), - - // the function to plot the chart - plotter: null, - - // The width of the lines connecting data points. - // This can be used to increase the contrast or some graphs. - strokeWidth: NETDATA.dataAttribute(state.element, 'dygraph-strokewidth', ((state.tmp.dygraph_chart_type === 'stacked') ? 0.1 : ((smooth === true) ? 1.5 : 0.7))), - strokePattern: NETDATA.dataAttribute(state.element, 'dygraph-strokepattern', undefined), - - // The size of the dot to draw on each point in pixels (see drawPoints). - // A dot is always drawn when a point is "isolated", - // i.e. there is a missing point on either side of it. - // This also controls the size of those dots. - drawPoints: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawpoints', false), - - // Draw points at the edges of gaps in the data. - // This improves visibility of small data segments or other data irregularities. - drawGapEdgePoints: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawgapedgepoints', true), - connectSeparatedPoints: NETDATA.chartLibraries.dygraph.isLogScale(state) ? false : NETDATA.dataAttributeBoolean(state.element, 'dygraph-connectseparatedpoints', false), - pointSize: NETDATA.dataAttribute(state.element, 'dygraph-pointsize', 1), - - // enabling this makes the chart with little square lines - stepPlot: NETDATA.dataAttributeBoolean(state.element, 'dygraph-stepplot', false), - - // Draw a border around graph lines to make crossing lines more easily - // distinguishable. Useful for graphs with many lines. - strokeBorderColor: NETDATA.dataAttribute(state.element, 'dygraph-strokebordercolor', NETDATA.themes.current.background), - strokeBorderWidth: NETDATA.dataAttribute(state.element, 'dygraph-strokeborderwidth', (state.tmp.dygraph_chart_type === 'stacked') ? 0.0 : 0.0), - fillGraph: NETDATA.dataAttribute(state.element, 'dygraph-fillgraph', (state.tmp.dygraph_chart_type === 'area' || state.tmp.dygraph_chart_type === 'stacked')), - fillAlpha: NETDATA.dataAttribute(state.element, 'dygraph-fillalpha', - ((state.tmp.dygraph_chart_type === 'stacked') - ? NETDATA.options.current.color_fill_opacity_stacked - : NETDATA.options.current.color_fill_opacity_area) - ), - stackedGraph: NETDATA.dataAttribute(state.element, 'dygraph-stackedgraph', (state.tmp.dygraph_chart_type === 'stacked')), - stackedGraphNaNFill: NETDATA.dataAttribute(state.element, 'dygraph-stackedgraphnanfill', 'none'), - drawAxis: drawAxis, - axisLabelFontSize: NETDATA.dataAttribute(state.element, 'dygraph-axislabelfontsize', 10), - axisLineColor: NETDATA.dataAttribute(state.element, 'dygraph-axislinecolor', NETDATA.themes.current.axis), - axisLineWidth: NETDATA.dataAttribute(state.element, 'dygraph-axislinewidth', 1.0), - drawGrid: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawgrid', true), - gridLinePattern: NETDATA.dataAttribute(state.element, 'dygraph-gridlinepattern', null), - gridLineWidth: NETDATA.dataAttribute(state.element, 'dygraph-gridlinewidth', 1.0), - gridLineColor: NETDATA.dataAttribute(state.element, 'dygraph-gridlinecolor', NETDATA.themes.current.grid), - maxNumberWidth: NETDATA.dataAttribute(state.element, 'dygraph-maxnumberwidth', 8), - sigFigs: NETDATA.dataAttribute(state.element, 'dygraph-sigfigs', null), - digitsAfterDecimal: NETDATA.dataAttribute(state.element, 'dygraph-digitsafterdecimal', 2), - valueFormatter: NETDATA.dataAttribute(state.element, 'dygraph-valueformatter', undefined), - highlightCircleSize: NETDATA.dataAttribute(state.element, 'dygraph-highlightcirclesize', highlightCircleSize), - highlightSeriesOpts: NETDATA.dataAttribute(state.element, 'dygraph-highlightseriesopts', null), // TOO SLOW: { strokeWidth: 1.5 }, - highlightSeriesBackgroundAlpha: NETDATA.dataAttribute(state.element, 'dygraph-highlightseriesbackgroundalpha', null), // TOO SLOW: (state.tmp.dygraph_chart_type === 'stacked')?0.7:0.5, - pointClickCallback: NETDATA.dataAttribute(state.element, 'dygraph-pointclickcallback', undefined), - visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names), - logscale: NETDATA.chartLibraries.dygraph.isLogScale(state) ? 'y' : undefined, - - // Expects a string in the format ":