diff --git a/admin/intro.php b/admin/intro.php index 0be9e70a2..af8fd8c97 100644 --- a/admin/intro.php +++ b/admin/intro.php @@ -187,6 +187,199 @@ SELECT MIN(date_available) trigger_notify('loc_end_intro'); +// +-----------------------------------------------------------------------+ +// | get activity data | +// +-----------------------------------------------------------------------+ + +$number_week = 4; +$date = new DateTime(); +//Array for the JS tooltip +$activity_last_weeks = array(); +//Count mondays +$mondays = 0; +//Get mondays date (day + month) for the chart legend +$mondays_date = array(); +//Array for sorting days in circle size +$temp_data = array(); + +//Get data from $number_week last weeks +while ($mondays < $number_week) +{ + $date_string = $date->format('Y-m-d'); + $query = ' +SELECT * + FROM `'.ACTIVITY_TABLE.'` + WHERE occured_on LIKE "'.$date_string.'%" +;'; + + $result = query2array($query, null); + + $this_day = array('number' => 0); + foreach ($result as $act) { + if(isset($this_day['details'][ucfirst($act['object'])][ucfirst($act['action'])])) + { + $this_day['details'][ucfirst($act['object'])][ucfirst($act['action'])] += 1; + } else { + $this_day['details'][ucfirst($act['object'])][ucfirst($act['action'])] = 1; + } + $this_day['number'] += 1; + } + + if ($this_day['number'] > 0) + { + $temp_data[] = array('x' => $this_day['number'], 'd'=>$date->format('N'), 'w'=>$mondays); + } + + + $activity_last_weeks[$mondays][intval($date->format('N'))] = $this_day; + + if ($date->format('D') == 'Mon') { + $mondays_date[$mondays]['m'] = $date->format('m'); + $mondays_date[$mondays]['d'] = $date->format('d'); + $mondays += 1; + } + $date->sub(new DateInterval('P1D')); +} + +// Algorithm to sort days in circle size : +// * Get the difference between sorted numbers of activity per day (only not null numbers) +// * Split days max $circle_sizes time on the biggest difference (but not below 120%) +// * Set the sizes according to the groups created + +//Function to sort days by number of activity +function cmp_day($a, $b) +{ + if ($a['x'] == $b['x']) { + return 0; + } + return ($a['x'] < $b['x']) ? -1 : 1; +} + +usort($temp_data, 'cmp_day'); + +//Get the percent difference +$diff_x = array(); + +for ($i=1; $i < count($temp_data); $i++) +{ + $diff_x[] = $temp_data[$i]['x']/$temp_data[$i-1]['x']*100; +} + +$split = 0; +//Split (split represented by -1) +while (max($diff_x) > 120) { + $diff_x[array_search(max($diff_x), $diff_x)] = -1; + $split++; +} + +//Fill empty chart data for the template +$chart_data = array(); +for ($i=0; $i < $number_week; $i++) { + for ($j=1; $j <= 7; $j++) { + $chart_data[$i][$j] = 0; + } +} + +$size = 1; +$chart_data[$temp_data[0]['w']][$temp_data[0]['d']] = $size; +//Set sizes in chart data +for ($i=1; $i < count($temp_data); $i++) { + if ($diff_x[$i-1] == -1) {$size++;} + $chart_data[$temp_data[$i]['w']][$temp_data[$i]['d']] = $size; +} + +//Assign data for the template +$template->assign('ACTIVITY_MONDAYS_DATE',array_reverse($mondays_date)); +$template->assign('ACTIVITY_LAST_WEEKS', array_reverse($activity_last_weeks)); +$template->assign('ACTIVITY_CHART_DATA',array_reverse($chart_data)); +$template->assign('ACTIVITY_CHART_NUMBER_SIZES',$size); + + +// +-----------------------------------------------------------------------+ +// | get storage data | +// +-----------------------------------------------------------------------+ + +$video_format = array('webm','webmv','ogg','ogv','mp4','m4v'); +$data_storage = array(); + +//Select files in Image_Table +$query = ' +SELECT file, filesize + FROM `'.IMAGES_TABLE.'` +;'; + +$result = query2array($query, null); + +foreach ($result as $file) +{ + $tabString = explode('.',$file['file']); + $ext = $tabString[count($tabString) -1]; + $size = $file['filesize']; + if (in_array($ext, $conf['picture_ext'])) + { + if (isset($data_storage['Photos'])) + { + $data_storage['Photos'] += $size; + } else { + $data_storage['Photos'] = $size; + } + } elseif (in_array($ext, $video_format)) { + if (isset($data_storage['Videos'])) + { + $data_storage['Videos'] += $size; + } else { + $data_storage['Videos'] = $size; + } + } else { + if (isset($data_storage['Others'])) + { + $data_storage['Others'] += $size; + } else { + $data_storage['Others'] = $size; + } + } +} + +//Select files from format table +$query = ' +SELECT SUM(filesize) + FROM `'.IMAGE_FORMAT_TABLE.'` +;'; + +$result = query2array($query); + +if (isset($result[0]['SUM(filesize)'])) +{ + $data_storage['Format'] = $result[0]['SUM(filesize)']; +} + +//If the host is not windows, get the cache size +if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') +{ + $f = './_data'; + $io = popen ( '/usr/bin/du -sk ' . $f, 'r' ); + $size = fgets ($io, 4096); + $size = substr ( $size, 0, strpos ( $size, "\t" ) ); + pclose ( $io ); + $data_storage['Cache'] = $size; +} + +//Calculate total storage +$total_storage = 0; +foreach ($data_storage as $value) +{ + $total_storage += $value; +} + +//Get percentage of the total storage +foreach ($data_storage as $key=>$value) +{ + $data_storage[$key] = $value/$total_storage*100; +} + +//Pass data to HTML +$template->assign('STORAGE_TOTAL',$total_storage/1000); +$template->assign('STORAGE_CHART_DATA',$data_storage); // +-----------------------------------------------------------------------+ // | sending html code | // +-----------------------------------------------------------------------+ diff --git a/admin/themes/default/template/intro.tpl b/admin/themes/default/template/intro.tpl index a9f253f8d..10602ff0a 100644 --- a/admin/themes/default/template/intro.tpl +++ b/admin/themes/default/template/intro.tpl @@ -7,7 +7,7 @@ var piwigo_need_update_msg = '{'A new version o var ext_need_update_msg = '{'Some upgrades are available for extensions.'|@translate|@escape:"javascript"} '; {literal} -jQuery().ready(function(){ + jQuery().ready(function(){ jQuery('.cluetip').cluetip({ width: 300, splitTitle: '|', @@ -61,6 +61,7 @@ jQuery().ready(function(){

{'Piwigo Administration'|@translate}

+
{if $NB_PHOTOS > 1} @@ -140,6 +141,52 @@ jQuery().ready(function(){
{* .stat-boxes *} +
+ +
{"Activity peak in the last weeks"|@translate}
+
+ {foreach from=$ACTIVITY_CHART_DATA item=WEEK_ACTIVITY key=WEEK_NUMBER} +
{"Week of %s/%s"|@translate:$ACTIVITY_MONDAYS_DATE[$WEEK_NUMBER]['d']:$ACTIVITY_MONDAYS_DATE[$WEEK_NUMBER]['m']}
+ {foreach from=$WEEK_ACTIVITY item=SIZE key=DAY_NUMBER} + + {if $SIZE != 0} +
+ {if $ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"] != 0} +

+ {"%s Activities"|@translate:$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"]} + {foreach from=$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["details"] item=actions key=cat} +
{$cat} : {foreach from=$actions item=number key=action} ({$action}) {$number} {/foreach} + {/foreach} +

+ {/if} + {/if} +
+ {/foreach} + {/foreach} +
+ {foreach from=array('Mon'|translate, 'Tue'|translate, 'Wed'|translate, 'Thu'|translate, 'Fri'|translate, 'Sat'|translate, 'Sun'|translate) item=day} +
{$day}
+ {/foreach} +
+ +
{"Storage"|@translate} {'%s MB used'|translate:$STORAGE_TOTAL}
+ +
+ {foreach from=$STORAGE_CHART_DATA item=value} +

{round($value)}%

+ {/foreach} +
+ +
+ {foreach from=$STORAGE_CHART_DATA item=i key=type} +

{$type|translate}

+ {/foreach} +
+ +
{* .intro-chart *} + +
{* .intro-page-container *} +

{if $ENABLE_SYNCHRONIZATION} {'Quick Local Synchronization'|translate} @@ -149,4 +196,4 @@ jQuery().ready(function(){ {if isset($SUBSCRIBE_BASE_URL)}
{'Subscribe %s to Piwigo Announcements Newsletter'|@translate:$EMAIL} {/if} -

+

\ No newline at end of file diff --git a/admin/themes/default/theme.css b/admin/themes/default/theme.css index 2647afbf9..b3429889f 100644 --- a/admin/themes/default/theme.css +++ b/admin/themes/default/theme.css @@ -545,14 +545,18 @@ FORM.properties SPAN.property { } /* Dashboard */ +.intro-page-container { + display: grid; + grid-template-columns: 41% 44%; +} + .stat-boxes { - text-align:left; - margin:40px 10px; + text-align:center; } .stat-box { display:inline-block; - width:200px; + width:150px; margin:10px 10px 40px 10px; color:#3b3b3b; text-align: center; @@ -565,7 +569,7 @@ div.stat-box { .stat-box i { display: inline-block; border-radius: 50%; - font-size: 37px; + font-size: 30px; padding: 20px; margin-bottom: 15px; } @@ -586,6 +590,212 @@ a.stat-box:hover { color:#777; } +.intro-charts { + width: 48vw; +} + +.chart-title { + font-size: 18px; + text-align: left; + font-weight: bold; + margin-bottom: 20px; + color: #3b3b3b; + position: relative; +} + +.chart-title-infos { + font-size: 14px; + position: absolute; + right: 0; + bottom: 0; +} + +.activity-chart { + font-weight: bold; + font-size: 14px; + display: grid; + grid-template-columns: repeat(8, 6vw) ; + grid-template-rows: repeat(4, 6vw); +} + +.activity-chart .row-legend,.activity-chart .col-legend { + position: relative; +} + +.activity-chart .row-legend { + display: flex; +} + +.activity-chart .row-legend div{ + margin: auto; +} + +.activity-chart .col-legend { + line-height: 6vw; +} + +.activity-chart .row-legend:after { + content: ""; + border-top: 2px solid black; + opacity: 0.05; + position: absolute; + width: 700%; + transform: translate(6vw,3vw); +} + +.activity-chart .col-legend .line-vertical { + border-left: 2px solid black; + opacity: 0.05; + position: absolute; + height: 250%; + left: 50%; + bottom: 100%; +} + +.activity-chart span { + display: flex; + overflow: visible; + position: relative; +} + +.activity-chart span div{ + height: 0px; + width: 0px; + background-color: #ff5252; + opacity: 0.8; + display: block; + border-radius: 100%; + z-index: 100; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.activity-chart span p { + position: absolute; + display: none; + opacity: 0; + z-index: 102; + font-size: 12px; + font-weight: normal; + background-color: white; + padding: 5px; + width: 150px; + box-shadow: 0px 0px 5px #acacac; + border-radius: 5px; + transform : translate(-50%, 5vw); + transition: ease 0.2s; + left: 50%; +} + +.activity-chart span p::after { + content: " "; + position: absolute; + bottom: 100%; /* At the bottom of the tooltip */ + left: 51%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent white transparent; +} + +.activity-chart span div:hover{ + padding: 0.5vw; +} + +.activity-chart span div:hover + p{ + display: block; + opacity: 1; +} + +.activity-chart #week-1-legend ~ span div { + background-color: #2883c3; +} + +.activity-chart #week-2-legend ~ span div { + background-color: #896af3 ; +} + +.activity-chart #week-3-legend ~ span div { + background-color: #6ece5e ; +} + +.activity-chart #week-4-legend ~ span div { + background-color: #ffa744 ; +} + +.storage-chart { + border-radius: 5px; + width: 100%; + overflow: hidden; + position: relative; + height: 30px; + display: flex; + background-color: #e8e8e8; +} + +.storage-chart span{ + opacity: 0.7; + transition: ease 0.2s; +} + +.storage-chart span p{ + font-weight: bold; + font-size: 16px; + color: black; + opacity: 0; + line-height: 0; + transition: ease 0.2s; +} + +.storage-chart span:hover{ + opacity: 1; +} + +.storage-chart span:hover p{ + opacity: 0.4; +} + +.storage-chart-legend { + display: flex +} + +.storage-chart-legend div{ + padding: 10px; + display: flex; + align-items: center; + font-size: 14px; +} + +.storage-chart-legend div span{ + width: 15px; + height: 15px; + display: block; + margin: 5px; + opacity: 0.7; +} + +.storage-chart span:nth-child(1), .storage-chart-legend div:nth-child(1) span{ + background-color:#ffa744; +} + +.storage-chart span:nth-child(2), .storage-chart-legend div:nth-child(2) span{ + background-color:#6ece5e; +} + +.storage-chart span:nth-child(3), .storage-chart-legend div:nth-child(3) span{ + background-color:#896af3; +} + +.storage-chart span:nth-child(4), .storage-chart-legend div:nth-child(4) span{ + background-color:#2883c3; +} + +.storage-chart span:nth-child(5), .storage-chart-legend div:nth-child(5) span{ + background-color:#ff5252; +} + #configContent fieldset { border:none; padding-left:20px; diff --git a/admin/themes/roma/theme.css b/admin/themes/roma/theme.css index ec75ed5d7..1f61b6d38 100644 --- a/admin/themes/roma/theme.css +++ b/admin/themes/roma/theme.css @@ -232,6 +232,19 @@ a.stat-box:hover { background-color: #555 } +.chart-title { + color: #777; +} + +.activity-chart span p { + background-color: #333333; + box-shadow: none; +} + +.activity-chart span p::after { + border-color: transparent transparent #333333 transparent; +} + /* hacks */ * html[lang="en"] body .content h2 , *+html[lang="en"] body .content h2 { text-transform:capitalize; } /* IE */ *+html .bigtext { left: 70px; } @@ -876,4 +889,4 @@ li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; .icon-green { background-color: #4ac641; color: #014400; -} \ No newline at end of file +}