Automatic WordPress security: local firewall, malware and file-integrity scanning, vulnerability protection, quarantine, scheduled backups, an optional page cache, and automatic global threat intelligence. See README.md for installation, update, and uninstall instructions.
142 lines
4.4 KiB
PHP
142 lines
4.4 KiB
PHP
<?php
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class Argus_Charts {
|
|
|
|
const PALETTE = array( '#3987e5', '#d95926', '#199e70', '#c98500', '#d55181', '#9085e9', '#e66767', '#17a2b8' );
|
|
|
|
public static function donut( array $data, $size = 168, $stroke = 24 ) {
|
|
$total = array_sum( $data );
|
|
if ( $total <= 0 ) {
|
|
return '';
|
|
}
|
|
|
|
$r = ( $size - $stroke ) / 2;
|
|
$c = $size / 2;
|
|
$circumference = 2 * M_PI * $r;
|
|
|
|
$segments = '';
|
|
$offset = 0;
|
|
$i = 0;
|
|
foreach ( $data as $label => $value ) {
|
|
if ( $value <= 0 ) {
|
|
continue;
|
|
}
|
|
$len = ( $value / $total ) * $circumference;
|
|
$color = self::PALETTE[ $i % count( self::PALETTE ) ];
|
|
|
|
$segments .= sprintf(
|
|
'<circle cx="%1$s" cy="%1$s" r="%2$s" fill="none" stroke="%3$s" stroke-width="%4$s" stroke-dasharray="%5$s %6$s" stroke-dashoffset="%7$s" stroke-linecap="butt" transform="rotate(-90 %1$s %1$s)"><title>%8$s: %9$s</title></circle>',
|
|
esc_attr( $c ),
|
|
esc_attr( $r ),
|
|
esc_attr( $color ),
|
|
esc_attr( $stroke ),
|
|
esc_attr( round( $len, 3 ) ),
|
|
esc_attr( round( $circumference - $len, 3 ) ),
|
|
esc_attr( round( -$offset, 3 ) ),
|
|
esc_html( $label ),
|
|
esc_html( number_format_i18n( $value ) )
|
|
);
|
|
$offset += $len;
|
|
$i++;
|
|
}
|
|
|
|
return sprintf(
|
|
'<svg viewBox="0 0 %1$d %1$d" class="argus-wpd-donut-svg" role="img" aria-label="%2$s">'
|
|
. '<circle cx="%3$s" cy="%3$s" r="%4$s" fill="none" stroke="var(--panel-2)" stroke-width="%5$s"></circle>'
|
|
. '%6$s'
|
|
. '<text x="%3$s" y="%3$s" text-anchor="middle" dominant-baseline="middle" class="argus-wpd-donut-total">%7$s</text>'
|
|
. '</svg>',
|
|
$size,
|
|
esc_attr__( 'Distribution chart', 'argus-wordpress-defence' ),
|
|
esc_attr( $c ),
|
|
esc_attr( $r ),
|
|
esc_attr( $stroke ),
|
|
$segments,
|
|
esc_html( number_format_i18n( $total ) )
|
|
);
|
|
}
|
|
|
|
public static function legend( array $data ) {
|
|
$total = array_sum( $data );
|
|
if ( $total <= 0 ) {
|
|
return '';
|
|
}
|
|
|
|
$html = '<div class="argus-wpd-donut-legend">';
|
|
$i = 0;
|
|
foreach ( $data as $label => $value ) {
|
|
if ( $value <= 0 ) {
|
|
continue;
|
|
}
|
|
$color = self::PALETTE[ $i % count( self::PALETTE ) ];
|
|
$pct = round( $value / $total * 100 );
|
|
|
|
$html .= sprintf(
|
|
'<div class="argus-wpd-donut-legend-row"><span class="argus-wpd-donut-swatch" style="background:%1$s"></span><span class="argus-wpd-donut-legend-label">%2$s</span><span class="argus-wpd-donut-legend-value">%3$s <em>(%4$s%%)</em></span></div>',
|
|
esc_attr( $color ),
|
|
esc_html( $label ),
|
|
esc_html( number_format_i18n( $value ) ),
|
|
esc_html( $pct )
|
|
);
|
|
$i++;
|
|
}
|
|
$html .= '</div>';
|
|
return $html;
|
|
}
|
|
|
|
public static function area_chart( array $series, $width = 640, $height = 160 ) {
|
|
$count = count( $series );
|
|
if ( $count < 2 ) {
|
|
return '';
|
|
}
|
|
|
|
$values = wp_list_pluck( $series, 'value' );
|
|
$max = max( 1, max( $values ) );
|
|
$pad_x = 8;
|
|
$pad_y = 10;
|
|
$plot_w = $width - ( $pad_x * 2 );
|
|
$plot_h = $height - ( $pad_y * 2 );
|
|
$step = $plot_w / ( $count - 1 );
|
|
|
|
$points = array();
|
|
foreach ( array_values( $values ) as $i => $value ) {
|
|
$x = $pad_x + ( $i * $step );
|
|
$y = $pad_y + $plot_h - ( ( $value / $max ) * $plot_h );
|
|
$points[] = array( round( $x, 2 ), round( $y, 2 ) );
|
|
}
|
|
|
|
$line_path = 'M ' . implode( ' L ', array_map( function ( $p ) {
|
|
return $p[0] . ' ' . $p[1];
|
|
}, $points ) );
|
|
|
|
$fill_path = $line_path
|
|
. sprintf( ' L %s %s', round( $pad_x + $plot_w, 2 ), round( $pad_y + $plot_h, 2 ) )
|
|
. sprintf( ' L %s %s Z', $pad_x, round( $pad_y + $plot_h, 2 ) );
|
|
|
|
$last = end( $points );
|
|
|
|
return sprintf(
|
|
'<svg viewBox="0 0 %1$d %2$d" class="argus-wpd-area-svg" role="img" aria-label="%3$s" preserveAspectRatio="none">'
|
|
. '<defs><linearGradient id="argusWpdAreaFill" x1="0" y1="0" x2="0" y2="1">'
|
|
. '<stop offset="0%%" stop-color="var(--cyan)" stop-opacity="0.35"></stop>'
|
|
. '<stop offset="100%%" stop-color="var(--cyan)" stop-opacity="0"></stop>'
|
|
. '</linearGradient></defs>'
|
|
. '<path d="%4$s" fill="url(#argusWpdAreaFill)" stroke="none"></path>'
|
|
. '<path d="%5$s" fill="none" stroke="var(--cyan)" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"></path>'
|
|
. '<circle cx="%6$s" cy="%7$s" r="3.5" fill="var(--cyan)"></circle>'
|
|
. '</svg>',
|
|
$width,
|
|
$height,
|
|
esc_attr__( 'Blocked requests over time', 'argus-wordpress-defence' ),
|
|
esc_attr( $fill_path ),
|
|
esc_attr( $line_path ),
|
|
esc_attr( $last[0] ),
|
|
esc_attr( $last[1] )
|
|
);
|
|
}
|
|
}
|