PluginProbe
WebTotem Security / 2.2.4
WebTotem Security v2.2.4
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / htdocs / js / Chart.js

Chart.js in WebTotem Security 2.2.4, at htdocs/js/Chart.js

265 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 if(typeof waf_chart == "object"){
2 const data = waf_chart;
3 drawLineChart(data);
4 }
5
6 async function drawLineChart(dataset) {
7 var diagram = document.getElementById('wtotem_chart_diagram');
8 var days = diagram.dataset.days;
9
10 const attacksAccessor = (d) => d.attacks;
11 const blockedAccessor = (d) => d.blocked;
12 const biggerAccessor = (d) =>
13 d.attacks > d.blocked ? d.attacks : d.blocked;
14 const dateParser = (days <= 1) ? d3.timeParse("%Y-%m-%d %H:%m:%M"): d3.timeParse("%Y-%m-%d");
15 const xAccessor = (d) => dateParser(d.date);
16
17
18 const chartWrapper = document.getElementById('line-chart')
19 let dimensions = {
20 width: chartWrapper.offsetWidth,
21 height: 251,
22 margin: {
23 top: 15,
24 right: 15,
25 bottom: 40,
26 left: 60,
27 },
28 };
29 dimensions.boundedWidth =
30 dimensions.width - dimensions.margin.left - dimensions.margin.right;
31 dimensions.boundedHeight =
32 dimensions.height - dimensions.margin.top - dimensions.margin.bottom;
33
34 const wrapper = d3
35 .select("#line-chart")
36 .append("svg")
37 .attr("width", dimensions.width)
38 .attr("height", dimensions.height);
39
40 const bounds = wrapper
41 .append("g")
42 .style(
43 "transform",
44 `translate(${dimensions.margin.left - 10}px, ${
45 dimensions.margin.top
46 }px)`
47 );
48
49 const yScale = d3
50 .scaleLinear()
51 .domain(d3.extent(dataset, biggerAccessor))
52 .range([dimensions.boundedHeight, 0]);
53 const xScale = d3
54 .scaleTime()
55 .domain(d3.extent(dataset, xAccessor))
56 .range([0, dimensions.boundedWidth]);
57
58 function make_y_gridlines() {
59 return d3.axisLeft(yScale).ticks(5);
60 }
61
62 bounds
63 .append("g")
64 .attr("class", "grid")
65 .call(
66 make_y_gridlines().tickSize(-dimensions.boundedWidth).tickFormat("")
67 );
68
69 const area1 = d3
70 .area()
71 .x((d) => xScale(xAccessor(d)))
72 .y0(dimensions.height)
73 .y1((d) => yScale(attacksAccessor(d)));
74
75 const area2 = d3
76 .area()
77 .x((d) => xScale(xAccessor(d)))
78 .y0(dimensions.height)
79 .y1((d) => yScale(blockedAccessor(d)));
80
81 bounds
82 .append("linearGradient")
83 .attr("id", "area-gradient1")
84 .attr("gradientUnits", "userSpaceOnUse")
85 .attr("x1", 0)
86 .attr("y1", yScale(0))
87 .attr("x2", 0)
88 .attr("y2", yScale(100))
89 .selectAll("stop")
90 .data([
91 { offset: "0%", color: "#d46c6a", opacity: 0 },
92 { offset: "100%", color: "#d46c6a", opacity: 0.6 },
93 ])
94 .enter()
95 .append("stop")
96 .attr("offset", function (d) {
97 return d.offset;
98 })
99 .attr("stop-color", function (d) {
100 return d.color;
101 })
102 .attr("stop-opacity", function (d) {
103 return d.opacity;
104 });
105
106 bounds
107 .append("linearGradient")
108 .attr("id", "area-gradient2")
109 .attr("gradientUnits", "userSpaceOnUse")
110 .attr("x1", 0)
111 .attr("y1", yScale(0))
112 .attr("x2", 0)
113 .attr("y2", yScale(100))
114 .selectAll("stop")
115 .data([
116 { offset: "0%", color: "#bace3d", opacity: 0 },
117 { offset: "100%", color: "#bace3d", opacity: 0.6 },
118 ])
119 .enter()
120 .append("stop")
121 .attr("offset", function (d) {
122 return d.offset;
123 })
124 .attr("stop-color", function (d) {
125 return d.color;
126 })
127 .attr("stop-opacity", function (d) {
128 return d.opacity;
129 });
130
131 const lineGenerator1 = d3
132 .line()
133 .x((d) => xScale(xAccessor(d)))
134 .y((d) => yScale(attacksAccessor(d)));
135 const lineGenerator2 = d3
136 .line()
137 .x((d) => xScale(xAccessor(d)))
138 .y((d) => yScale(attacksAccessor(d)));
139
140 const line1 = bounds
141 .append("path")
142 .datum(dataset)
143 .attr("d", lineGenerator1(dataset))
144 .attr("class", "area")
145 .attr("d", area1)
146 .style("fill", "url(#area-gradient1)");
147
148 const line2 = bounds
149 .append("path")
150 .datum(dataset)
151 .attr("d", lineGenerator2(dataset))
152 .attr("class", "area")
153 .attr("d", area2)
154 .style("fill", "url(#area-gradient2)");
155
156 const yAxisGenerator = d3.axisLeft().scale(yScale);
157 const xAxisGenerator = d3.axisBottom().scale(xScale);
158 const yAxis = bounds.append("g").attr("class", "axis").call(yAxisGenerator);
159 const xAxis = bounds
160 .append("g")
161 .call(xAxisGenerator)
162 .attr("class", "axis")
163 .style("transform", `translateY(${dimensions.boundedHeight}px)`);
164
165 const listeningRect = bounds
166 .append("rect")
167 .attr("class", "listening-rect")
168 .attr("width", dimensions.boundedWidth)
169 .attr("height", dimensions.boundedHeight)
170 .on("mousemove", onMouseMove)
171 .on("mouseleave", onMouseLeave);
172
173 const tooltipAttacks = d3.select("#tooltipAttacks");
174 const tooltipBlocked = d3.select("#tooltipBlocked");
175 const tooltipCircle1 = bounds
176 .append("circle")
177 .attr("class", "tooltip-circle")
178 .attr("r", 4)
179 .attr("stroke", "#F3F5F6")
180 .attr("fill", "#1D293F")
181 .attr("stroke-width", 2)
182 .style("opacity", 0);
183 const tooltipCircle2 = bounds
184 .append("circle")
185 .attr("class", "tooltip-circle")
186 .attr("r", 4)
187 .attr("stroke", "#F3F5F6")
188 .attr("fill", "#1D293F")
189 .attr("stroke-width", 2)
190 .style("opacity", 0);
191 function onMouseMove() {
192 const mousePosition = d3.mouse(this);
193 const hoveredDate = xScale.invert(mousePosition[0]);
194
195 const getDistanceFromHoveredDate = (d) =>
196 Math.abs(xAccessor(d) - hoveredDate);
197 const closestIndex = d3.scan(
198 dataset,
199 (a, b) =>
200 getDistanceFromHoveredDate(a) - getDistanceFromHoveredDate(b)
201 );
202 const closestDataPoint = dataset[closestIndex];
203
204 const closestXValue = xAccessor(closestDataPoint);
205 const closestAttacksValue = attacksAccessor(closestDataPoint);
206 const closestBlockedValue = blockedAccessor(closestDataPoint);
207
208 const x = xScale(closestXValue) + dimensions.margin.left + 8;
209 const yAttacks =
210 yScale(closestAttacksValue) + dimensions.margin.top + 10;
211 const yBlocked =
212 yScale(closestBlockedValue) + dimensions.margin.top + 10;
213
214 tooltipAttacks.style(
215 "transform",
216 `translate(` +
217 `calc( -50% + ${x}px),` +
218 `calc(-100% + ${yAttacks}px)` +
219 `)`
220 );
221 tooltipBlocked.style(
222 "transform",
223 `translate(` +
224 `calc( -50% + ${x}px),` +
225 `calc(-100% + ${yBlocked}px)` +
226 `)`
227 );
228
229 tooltipAttacks.style("opacity", 1);
230 tooltipBlocked.style("opacity", 1);
231
232 tooltipAttacks.select("#countAttacks").html(closestAttacksValue);
233 tooltipBlocked.select("#countBlocked").html(closestBlockedValue);
234 tooltipCircle1
235 .attr("cx", xScale(closestXValue))
236 .attr("cy", yScale(closestAttacksValue))
237 .style("opacity", 1);
238 tooltipCircle2
239 .attr("cx", xScale(closestXValue))
240 .attr("cy", yScale(closestBlockedValue))
241 .style("opacity", 1);
242 }
243
244 function onMouseLeave() {
245 tooltipAttacks.style("opacity", 0);
246 tooltipBlocked.style("opacity", 0);
247
248 tooltipCircle1.style("opacity", 0);
249 tooltipCircle2.style("opacity", 0);
250 }
251 }
252
253
254 var resizeTimer;
255 window.onresize = function (event) {
256 clearTimeout(resizeTimer);
257 resizeTimer = setTimeout(function () {
258 var s = d3.select("#line-chart").selectAll("svg");
259 s = s.remove();
260 if(typeof data != "undefined"){
261 drawLineChart(data);
262 }
263 }, 10);
264 };
265