]> source.dussan.org Git - rspamd.git/commitdiff
[WebUI] Add graph tab
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 31 Jan 2017 15:48:57 +0000 (15:48 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 31 Jan 2017 15:48:57 +0000 (15:48 +0000)
interface/js/app/graph.js [new file with mode: 0644]
interface/js/app/rspamd.js
interface/js/app/stats.js

diff --git a/interface/js/app/graph.js b/interface/js/app/graph.js
new file mode 100644 (file)
index 0000000..2d53414
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ The MIT License (MIT)
+
+ Copyright (C) 2017 Vsevolod Stakhov <vsevolod@highsecure.ru>
+ Copyright (C) 2017 Alexander Moisseev
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+
+define(['jquery', 'd3evolution', 'humanize'],
+function($, D3Evolution) {
+    var rrd_pie_config = {
+        header: {},
+        size: {
+            canvasWidth: 400,
+            canvasHeight: 180,
+            pieInnerRadius: "20%",
+            pieOuterRadius: "80%"
+        },
+        labels: {
+            outer: {
+                format: "none"
+            },
+            inner: {
+                hideWhenLessThanPercentage: 8
+            },
+        },
+        misc: {
+            pieCenterOffset: {
+                x: -120,
+                y: 10,
+            },
+            gradient: {
+                enabled: true,
+            },
+        },
+    };
+
+    var graph_options = {
+        title: "Rspamd throughput",
+        width: 1060,
+        height: 370,
+        yAxisLabel: "Message rate, msg/s",
+
+        legend: {
+            space: 140,
+            entries: [{
+                label: "Rejected",
+                color: "#FF0000"
+            }, {
+                label: "Temporary rejected",
+                color: "#BF8040"
+            }, {
+                label: "Subject rewrited",
+                color: "#FF6600"
+            }, {
+                label: "Probable spam",
+                color: "#FFAD00"
+            }, {
+                label: "Greylisted",
+                color: "#436EEE"
+            }, {
+                label: "Clean",
+                color: "#66CC00"
+            }]
+        }
+    };
+
+    function initGraph() {
+        // Get selectors' current state
+        function getSelector(id) {
+            var e = document.getElementById(id);
+            return e.options[e.selectedIndex].value;
+        }
+        var graph = new D3Evolution("graph", $.extend({}, graph_options, {
+            type:        getSelector("selType"),
+            interpolate: getSelector("selInterpolate"),
+            convert:     getSelector("selConvert"),
+        }));
+        $("#selConvert").change(function () {
+            graph.convert(this.value);
+        });
+        $("#selType").change(function () {
+            graph.type(this.value);
+        });
+        $("#selInterpolate").change(function () {
+            graph.interpolate(this.value);
+        });
+
+        return graph;
+    }
+
+    function getRrdSummary(json) {
+        var xExtents = d3.extent(d3.merge(json), function (d) { return d.x; });
+        var timeInterval = xExtents[1] - xExtents[0];
+
+        return json.map(function (curr, i) {
+            var avg = d3.mean(curr, function (d) { return d.y; });
+            var yExtents = d3.extent(curr, function (d) { return d.y; });
+
+            return {
+                label: graph_options.legend.entries[i].label,
+                value: avg && (avg * timeInterval) ^ 0,
+                min: yExtents[0],
+                avg: avg && avg.toFixed(6),
+                max: yExtents[1],
+                last: curr[curr.length - 1].y,
+                color: graph_options.legend.entries[i].color,
+            };
+        }, []);
+    }
+
+    function drawRrdTable(data) {
+        $('#rrd-table').DataTable({
+            destroy: true,
+            paging: false,
+            searching: false,
+            info: false,
+            data: data,
+            columns: [
+                { data: "label", title: "Action" },
+                { data: "value", title: "Messages",       defaultContent: "" },
+                { data: "min",   title: "Minimum, msg/s", defaultContent: "" },
+                { data: "avg",   title: "Average, msg/s", defaultContent: "" },
+                { data: "max",   title: "Maximum, msg/s", defaultContent: "" },
+                { data: "last",  title: "Last, msg/s" },
+            ],
+
+            "fnRowCallback": function (nRow, aData) {
+                $(nRow).css("color", aData.color);
+            }
+        });
+    }
+
+    var interface = {};
+
+    interface.draw = function(rspamd, graphs, checked_server, type) {
+        if (graphs.graph === undefined) {
+            graphs.graph = initGraph();
+        }
+
+        if (type === undefined) {
+            function getSelector(id) {
+                var e = document.getElementById(id);
+                return e.options[e.selectedIndex].value;
+            }
+            type = getSelector("selData");
+        }
+
+        $.ajax({
+            dataType: 'json',
+            type: 'GET',
+            url: 'graph',
+            jsonp: false,
+            data: {
+                "type": type
+            },
+            beforeSend: function (xhr) {
+                xhr.setRequestHeader('Password', rspamd.getPassword());
+            },
+            success: function (data) {
+                var rrd_summary = getRrdSummary(data);
+                graphs.graph.data(data);
+                graphs.rrd_pie = rspamd.drawPie(graphs.rrd_pie,
+                    "rrd-pie",
+                    rrd_summary,
+                    rrd_pie_config);
+                drawRrdTable(rrd_summary);
+            },
+            error: function (jqXHR, textStatus, errorThrown) {
+                rspamd.alertMessage('alert-error', 'Cannot receive throughput data: ' +
+                    textStatus + ' ' + jqXHR.status + ' ' + errorThrown);
+            }
+        });
+    };
+
+
+    return interface;
+});
index 800ad20fe15457f7d2ec2f50b9f6903ab792ec49..a7d3f41561553c867ee9493229d58e7e2dce817f 100644 (file)
@@ -22,8 +22,8 @@
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  */
-define(['jquery', 'visibility', 'bootstrap'],
-    function ($, D3Evolution, d3pie, visibility, DataTable) {
+define(['jquery', 'd3pie', 'visibility', 'bootstrap'],
+    function ($, d3pie, visibility, DataTable) {
         // begin
         var graphs = {};
         var tables = {};
@@ -94,13 +94,18 @@ define(['jquery', 'visibility', 'bootstrap'],
                     });
                     break;
                 case "#throughput_nav":
-                    getGraphData(selData);
+                    require(['app/graph'], function(graph) {
+                        graph.draw(interface, graphs, checked_server, selData);
+                    });
+
                     var autoRefresh = {
                         hourly: 60000,
                         daily: 300000
                     };
                     timer_id.throughput = Visibility.every(autoRefresh[selData] || 3600000, function () {
-                        getGraphData(selData);
+                        require(['app/graph'], function(graph) {
+                            graph.draw(interface, graphs, checked_server, selData);
+                        });
                     });
                     break;
                 case "#configuration_nav":
@@ -172,15 +177,6 @@ define(['jquery', 'visibility', 'bootstrap'],
                 selData = this.value;
                 tabClick("#throughput_nav");
             });
-            $("#selConvert").change(function () {
-                graph.convert(this.value);
-            });
-            $("#selType").change(function () {
-                graph.type(this.value);
-            });
-            $("#selInterpolate").change(function () {
-                graph.interpolate(this.value);
-            });
             $.ajaxSetup({
                 timeout: 2000,
                 jsonp: false
@@ -389,6 +385,98 @@ define(['jquery', 'visibility', 'bootstrap'],
             });
         };
 
+        interface.drawPie = function(obj, id, data, conf) {
+            if (obj) {
+                obj.updateProp("data.content",
+                    data.filter(function (elt) {
+                        return elt.value > 0;
+                    })
+                );
+            } else {
+                obj = new d3pie(id,
+                    $.extend({}, {
+                        "header": {
+                            "title": {
+                                "text": "Rspamd filter stats",
+                                "fontSize": 24,
+                                "font": "open sans"
+                            },
+                            "subtitle": {
+                                "color": "#999999",
+                                "fontSize": 12,
+                                "font": "open sans"
+                            },
+                            "titleSubtitlePadding": 9
+                        },
+                        "footer": {
+                            "color": "#999999",
+                            "fontSize": 10,
+                            "font": "open sans",
+                            "location": "bottom-left"
+                        },
+                        "size": {
+                            "canvasWidth": 600,
+                            "canvasHeight": 400,
+                            "pieInnerRadius": "20%",
+                            "pieOuterRadius": "85%"
+                        },
+                        "data": {
+                            //"sortOrder": "value-desc",
+                            "content": data.filter(function (elt) {
+                                return elt.value > 0;
+                            })
+                        },
+                        "labels": {
+                            "outer": {
+                                "hideWhenLessThanPercentage": 1,
+                                "pieDistance": 30
+                            },
+                            "inner": {
+                                "hideWhenLessThanPercentage": 4
+                            },
+                            "mainLabel": {
+                                "fontSize": 14
+                            },
+                            "percentage": {
+                                "color": "#eeeeee",
+                                "fontSize": 14,
+                                "decimalPlaces": 0
+                            },
+                            "lines": {
+                                "enabled": true
+                            },
+                            "truncation": {
+                                "enabled": true
+                            }
+                        },
+                        "tooltips": {
+                            "enabled": true,
+                            "type": "placeholder",
+                            "string": "{label}: {value}, {percentage}%"
+                        },
+                        "effects": {
+                            "pullOutSegmentOnClick": {
+                                "effect": "back",
+                                "speed": 400,
+                                "size": 8
+                            },
+                            "load": {
+                                "effect": "none"
+                            }
+                        },
+                        "misc": {
+                            "gradient": {
+                                "enabled": true,
+                                "percentage": 100
+                            }
+                        }
+                    }, conf));
+            }
+            return obj;
+        };
+
+        interface.getPassword = getPassword;
+
         return interface;
 
         // @alert popover
@@ -500,145 +588,7 @@ define(['jquery', 'visibility', 'bootstrap'],
             $('#modalBody form').hide();
         });
 
-        var rrd_pie_config = {
-            header: {},
-            size: {
-                canvasWidth: 400,
-                canvasHeight: 180,
-                pieInnerRadius: "20%",
-                pieOuterRadius: "80%"
-            },
-            labels: {
-                outer: {
-                    format: "none"
-                },
-                inner: {
-                    hideWhenLessThanPercentage: 8
-                },
-            },
-            misc: {
-                pieCenterOffset: {
-                    x: -120,
-                    y: 10,
-                },
-                gradient: {
-                    enabled: true,
-                },
-            },
-        };
 
-        var graph_options = {
-            title: "Rspamd throughput",
-            width: 1060,
-            height: 370,
-            yAxisLabel: "Message rate, msg/s",
-
-            legend: {
-                space: 140,
-                entries: [{
-                    label: "Rejected",
-                    color: "#FF0000"
-                }, {
-                    label: "Temporary rejected",
-                    color: "#BF8040"
-                }, {
-                    label: "Subject rewrited",
-                    color: "#FF6600"
-                }, {
-                    label: "Probable spam",
-                    color: "#FFAD00"
-                }, {
-                    label: "Greylisted",
-                    color: "#436EEE"
-                }, {
-                    label: "Clean",
-                    color: "#66CC00"
-                }]
-            }
-        };
-
-        function initGraph() {
-            // Get selectors' current state
-            function getSelector(id) {
-                var e = document.getElementById(id);
-                return e.options[e.selectedIndex].value;
-            }
-
-            selData = getSelector("selData");
-
-            graph = new D3Evolution("graph", $.extend({}, graph_options, {
-                type:        getSelector("selType"),
-                interpolate: getSelector("selInterpolate"),
-                convert:     getSelector("selConvert"),
-            }));
-        }
-
-        function getRrdSummary(json) {
-            var xExtents = d3.extent(d3.merge(json), function (d) { return d.x; });
-            var timeInterval = xExtents[1] - xExtents[0];
-
-            return json.map(function (curr, i) {
-                var avg = d3.mean(curr, function (d) { return d.y; });
-                var yExtents = d3.extent(curr, function (d) { return d.y; });
-
-                return {
-                    label: graph_options.legend.entries[i].label,
-                    value: avg && (avg * timeInterval) ^ 0,
-                    min: yExtents[0],
-                    avg: avg && avg.toFixed(6),
-                    max: yExtents[1],
-                    last: curr[curr.length - 1].y,
-                    color: graph_options.legend.entries[i].color,
-                };
-            }, []);
-        }
-
-        function drawRrdTable(data) {
-            $('#rrd-table').DataTable({
-                destroy: true,
-                paging: false,
-                searching: false,
-                info: false,
-                data: data,
-                columns: [
-                    { data: "label", title: "Action" },
-                    { data: "value", title: "Messages",       defaultContent: "" },
-                    { data: "min",   title: "Minimum, msg/s", defaultContent: "" },
-                    { data: "avg",   title: "Average, msg/s", defaultContent: "" },
-                    { data: "max",   title: "Maximum, msg/s", defaultContent: "" },
-                    { data: "last",  title: "Last, msg/s" },
-                ],
-
-                "fnRowCallback": function (nRow, aData) {
-                    $(nRow).css("color", aData.color);
-                }
-            });
-        }
-
-        function getGraphData(type) {
-            $.ajax({
-                dataType: 'json',
-                type: 'GET',
-                url: 'graph',
-                jsonp: false,
-                data: {
-                    "type": type
-                },
-                beforeSend: function (xhr) {
-                    xhr.setRequestHeader('Password', getPassword());
-                },
-                success: function (data) {
-                    const rrd_summary = getRrdSummary(data);
-                    graph.data(data);
-                    rrd_pie = drawPie(rrd_pie, "rrd-pie", rrd_summary, rrd_pie_config);
-                    drawRrdTable(rrd_summary);
-                },
-                error: function (jqXHR, textStatus, errorThrown) {
-                    alertMessage('alert-error', 'Cannot receive throughput data: ' +
-                        textStatus + ' ' + jqXHR.status + ' ' + errorThrown);
-                }
-            });
-        }
 
         // @get history log
         // function getChart() {
index 51e13b385aaf2f60ea06261dfe8efa212c4617a8..e2ce33d0fcafcbdaeb58a8715b60a7e5014c814a 100644 (file)
@@ -139,7 +139,7 @@ function($, d3pie, Humanize) {
         $(widgets).show();
     }
 
-     function getChart(pie, checked_server) {
+     function getChart(rspamd, pie, checked_server) {
         var creds = JSON.parse(sessionStorage.getItem('Credentials'));
         if (creds && creds[checked_server]) {
             var data = creds[checked_server].data;
@@ -169,100 +169,10 @@ function($, d3pie, Humanize) {
                 "data" : data.reject,
                 "value" : data.reject
             } ];
-            return drawPie(pie, "chart", new_data);
-        }
-    }
 
-    function drawPie(obj, id, data, conf) {
-        if (obj) {
-            obj.updateProp("data.content",
-                data.filter(function (elt) {
-                    return elt.value > 0;
-                })
-            );
-        } else {
-            obj = new d3pie(id,
-                $.extend({}, {
-                    "header": {
-                        "title": {
-                            "text": "Rspamd filter stats",
-                            "fontSize": 24,
-                            "font": "open sans"
-                        },
-                        "subtitle": {
-                            "color": "#999999",
-                            "fontSize": 12,
-                            "font": "open sans"
-                        },
-                        "titleSubtitlePadding": 9
-                    },
-                    "footer": {
-                        "color": "#999999",
-                        "fontSize": 10,
-                        "font": "open sans",
-                        "location": "bottom-left"
-                    },
-                    "size": {
-                        "canvasWidth": 600,
-                        "canvasHeight": 400,
-                        "pieInnerRadius": "20%",
-                        "pieOuterRadius": "85%"
-                    },
-                    "data": {
-                        //"sortOrder": "value-desc",
-                        "content": data.filter(function (elt) {
-                            return elt.value > 0;
-                        })
-                    },
-                    "labels": {
-                        "outer": {
-                            "hideWhenLessThanPercentage": 1,
-                            "pieDistance": 30
-                        },
-                        "inner": {
-                            "hideWhenLessThanPercentage": 4
-                        },
-                        "mainLabel": {
-                            "fontSize": 14
-                        },
-                        "percentage": {
-                            "color": "#eeeeee",
-                            "fontSize": 14,
-                            "decimalPlaces": 0
-                        },
-                        "lines": {
-                            "enabled": true
-                        },
-                        "truncation": {
-                            "enabled": true
-                        }
-                    },
-                    "tooltips": {
-                        "enabled": true,
-                        "type": "placeholder",
-                        "string": "{label}: {value}, {percentage}%"
-                    },
-                    "effects": {
-                        "pullOutSegmentOnClick": {
-                            "effect": "back",
-                            "speed": 400,
-                            "size": 8
-                        },
-                        "load": {
-                            "effect": "none"
-                        }
-                    },
-                    "misc": {
-                        "gradient": {
-                            "enabled": true,
-                            "percentage": 100
-                        }
-                    }
-                }, conf));
+            return rspamd.drawPie(pie, "chart", new_data);
         }
-        return obj;
     }
-
     // Public API
     var interface = {
         statWidgets: function(rspamd, graphs, checked_server) {
@@ -311,7 +221,7 @@ function($, d3pie, Humanize) {
                 });
                 sessionStorage.setItem("Credentials", JSON.stringify(to_Credentials));
                 displayStatWidgets(checked_server);
-                graphs.chart = getChart(graphs.chart, checked_server);
+                graphs.chart = getChart(rspamd, graphs.chart, checked_server);
             },
             function (serv, jqXHR, textStatus, errorThrown) {
                 var alert_status = serv.name + '_alerted';
@@ -327,4 +237,4 @@ function($, d3pie, Humanize) {
 
     return interface;
 }
-);
\ No newline at end of file
+);