Issue #1190 : Dashboard Charts Modifications

* Number of weeks for Activity Chart is now in configuration file
 * Tooltip change for activity chart and add for storage chart
 * General page design change
This commit is contained in:
Zacharie
2020-06-04 14:42:09 +02:00
committed by plegall
parent 2633042618
commit 5aef3ebbbd
5 changed files with 223 additions and 85 deletions

View File

@@ -191,54 +191,70 @@ trigger_notify('loc_end_intro');
// | get activity data |
// +-----------------------------------------------------------------------+
$number_week = 4;
$nb_weeks = $conf['dashboard_activity_nb_weeks'];
$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();
//Get mondays number for the chart legend
$week_number = array();
//Array for sorting days in circle size
$temp_data = array();
//Get data from $number_week last weeks
while ($mondays < $number_week)
//Get data from $nb_weeks last weeks
while ($mondays < $nb_weeks)
{
$date_string = $date->format('Y-m-d');
$query = '
SELECT *
FROM `'.ACTIVITY_TABLE.'`
WHERE occured_on LIKE "'.$date_string.'%"
;';
$date->sub(new DateInterval('P1D'));
$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)
if ($date->format('D') == 'Mon')
{
$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');
$week_number[] = $date->format('W');
$mondays += 1;
}
$date->sub(new DateInterval('P1D'));
}
$week_number = array_reverse($week_number);
$date_string = $date->format('Y-m-d');
$query = '
SELECT *
FROM `'.ACTIVITY_TABLE.'`
WHERE occured_on >= "'.$date_string.'%"
;';
$result = query2array($query, null);
foreach ($result as $row)
{
$day_date = new DateTime($row['occured_on']);
$week = 0;
for ($i=0; $i < $nb_weeks; $i++)
{
if ($week_number[$i] == $day_date->format('W'))
{
$week = $i;
}
}
$day_nb = $day_date->format('N');
@$activity_last_weeks[$week][$day_nb]['details'][ucfirst($row['object'])][ucfirst($row['action'])] += 1;
@$activity_last_weeks[$week][$day_nb]['number'] += 1;
@$activity_last_weeks[$week][$day_nb]['date'] = format_date($day_date->getTimestamp());
}
//echo '<pre>'; print_r($activity_last_weeks); echo '</pre>';
foreach($activity_last_weeks as $week => $i)
{
foreach($i as $day => $j)
{
if ($j['number'] > 0)
{
$temp_data[] = array('x' => $j['number'], 'd'=>$day, 'w'=>$week);
}
}
}
// Algorithm to sort days in circle size :
@@ -249,7 +265,8 @@ SELECT *
//Function to sort days by number of activity
function cmp_day($a, $b)
{
if ($a['x'] == $b['x']) {
if ($a['x'] == $b['x'])
{
return 0;
}
return ($a['x'] < $b['x']) ? -1 : 1;
@@ -267,15 +284,18 @@ for ($i=1; $i < count($temp_data); $i++)
$split = 0;
//Split (split represented by -1)
while (max($diff_x) > 120) {
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++) {
for ($i=0; $i < $nb_weeks; $i++)
{
for ($j=1; $j <= 7; $j++)
{
$chart_data[$i][$j] = 0;
}
}
@@ -283,18 +303,21 @@ for ($i=0; $i < $number_week; $i++) {
$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++;}
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_WEEK_NUMBER',$week_number);
$template->assign('ACTIVITY_LAST_WEEKS', $activity_last_weeks);
$template->assign('ACTIVITY_CHART_DATA',$chart_data);
$template->assign('ACTIVITY_CHART_NUMBER_SIZES',$size);
// +-----------------------------------------------------------------------+
// | get storage data |
// +-----------------------------------------------------------------------+
@@ -350,7 +373,7 @@ $result = query2array($query);
if (isset($result[0]['SUM(filesize)']))
{
$data_storage['Format'] = $result[0]['SUM(filesize)'];
$data_storage['Formats'] = $result[0]['SUM(filesize)'];
}
//If the host is not windows, get the cache size
@@ -371,14 +394,8 @@ 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_TOTAL',$total_storage);
$template->assign('STORAGE_CHART_DATA',$data_storage);
// +-----------------------------------------------------------------------+
// | sending html code |

View File

@@ -46,6 +46,25 @@ var ext_need_update_msg = '<a href="admin.php?page=updates&amp;tab=ext">{'Some u
}
});
});
//Tooltip for the storage chart
$('.storage-chart span').each(function () {
let tooltip = $('.storage-tooltips #'+$(this).data('type'));
let left = $(this).position().left + $(this).width()/2 - tooltip.innerWidth()/2;
tooltip.css('left', left+"px")
$(this).hover(function() {
tooltip.toggle();
});
});
$(window).on('resize', function(){
$('.storage-chart span').each(function () {
let tooltip = $('.storage-tooltips #'+$(this).data('type'));
let left = $(this).position().left + $(this).width()/2 - tooltip.innerWidth()/2;
tooltip.css('left', left+"px")
});
});
{/literal}
{/footer_script}
@@ -144,18 +163,41 @@ var ext_need_update_msg = '<a href="admin.php?page=updates&amp;tab=ext">{'Some u
<div class="intro-charts">
<div class="chart-title"> {"Activity peak in the last weeks"|@translate}</div>
<div class="activity-chart" style="grid-template-rows: repeat({count($ACTIVITY_CHART_DATA) + 1}, 6vw);">
<div class="activity-chart" style="grid-template-rows: repeat({count($ACTIVITY_CHART_DATA) + 1}, 5vw);">
{foreach from=$ACTIVITY_CHART_DATA item=WEEK_ACTIVITY key=WEEK_NUMBER}
<div id="week-{$WEEK_NUMBER}-legend" class="row-legend"><div>{"Week of %s/%s"|@translate:$ACTIVITY_MONDAYS_DATE[$WEEK_NUMBER]['d']:$ACTIVITY_MONDAYS_DATE[$WEEK_NUMBER]['m']}</div></div>
<div id="week-{$WEEK_NUMBER}-legend" class="row-legend"><div>{"Week %s"|@translate:$ACTIVITY_WEEK_NUMBER[$WEEK_NUMBER]}</div></div>
{foreach from=$WEEK_ACTIVITY item=SIZE key=DAY_NUMBER}
<span>
{if $SIZE != 0}
<div id="day{$WEEK_NUMBER}-{$DAY_NUMBER}" style="height:{$SIZE/$ACTIVITY_CHART_NUMBER_SIZES * 7 + 1}vw;width:{$SIZE/$ACTIVITY_CHART_NUMBER_SIZES * 7 + 1}vw;opacity:{$SIZE/$ACTIVITY_CHART_NUMBER_SIZES * 0.7 + 0.1}"></div>
{if $ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"] != 0}
<p style="transform: translate(-50%, 50%) translate(0, {if $SIZE/2 >= 1}{$SIZE/2}{else}2{/if}vw)">
<b>{"%s Activities"|@translate:$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"]}</b>
{assign var='SIZE_IN_UNIT' value=$SIZE/$ACTIVITY_CHART_NUMBER_SIZES * 5 + 1}
{assign var='OPACITY_IN_UNIT' value=$SIZE/$ACTIVITY_CHART_NUMBER_SIZES * 0.6 + 0.2}
<div id="day{$WEEK_NUMBER}-{$DAY_NUMBER}" style="height:{$SIZE_IN_UNIT}vw;width:{$SIZE_IN_UNIT}vw;opacity:{$OPACITY_IN_UNIT}"></div>
{if $ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"] != 0}
<p class="tooltip" style="transform: translate(-50%,{$SIZE_IN_UNIT/2}vw);">
<span class="tooltip-header">
<span class="tooltip-title">{if $ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"] > 1}{"%s Activities"|@translate:$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"]}{else}{"%s Activity"|@translate:$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["number"]}{/if}</span>
<span class="tooltip-date">{$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["date"]}</span>
</span>
<span class="tooltip-details">
{foreach from=$ACTIVITY_LAST_WEEKS[$WEEK_NUMBER][$DAY_NUMBER]["details"] item=actions key=cat}
<br> {$cat} : {foreach from=$actions item=number key=action} ({$action}) {$number} {/foreach}
<span class="tooltip-details-cont">
{if $cat == "Group"} <span class="icon-group icon-purple tooltip-details-title">{$cat|@translate}</span>
{elseif $cat == "User"} <span class="icon-users icon-purple tooltip-details-title"> {$cat|@translate}</span>
{elseif $cat == "Album"} <span class="icon-sitemap icon-red tooltip-details-title">{$cat|@translate}</span>
{elseif $cat == "Photo"} <span class="icon-picture icon-yellow tooltip-details-title">{$cat|@translate} </span>
{elseif $cat == "Tag"} <span class="icon-tags icon-green tooltip-details-title">{$cat|@translate} </span>
{else} <span class="tooltip-details-title"> {$cat|@translate} </span> {/if}
{foreach from=$actions item=number key=action}
{if $action == "Edit"} <span class="icon-pencil tooltip-detail" title="{"%s editions"|@translate:$number}">{$number}</span>
{elseif $action == "Add"} <span class="icon-plus tooltip-detail" title="{"%s additions"|@translate:$number}">{$number}</span>
{elseif $action == "Delete"} <span class="icon-trash tooltip-detail" title="{"%s deletions"|@translate:$number}">{$number}</span>
{elseif $action == "Login"} <span class="icon-key tooltip-detail" title="{"%s login"|@translate:$number}">{$number}</span>
{elseif $action == "Logout"} <span class="icon-logout tooltip-detail" title="{"%s logout"|@translate:$number}">{$number} </span>
{else} <span> ({$action|@translate}) {$number} </span>
{/if}
{/foreach}
</span>
{/foreach}
</p>
{/if}
@@ -169,11 +211,19 @@ var ext_need_update_msg = '<a href="admin.php?page=updates&amp;tab=ext">{'Some u
{/foreach}
</div>
<div class="chart-title"> {"Storage"|@translate} <span class="chart-title-infos"> {'%s MB used'|translate:$STORAGE_TOTAL} </span></div>
<div class="chart-title"> {"Storage"|@translate} <span class="chart-title-infos"> {'%s MB used'|translate:($STORAGE_TOTAL/1000)} </span></div>
<div class="storage-chart">
{foreach from=$STORAGE_CHART_DATA item=value}
<span style="width:{$value}%"> <p>{round($value)}%</p> </span>
{foreach from=$STORAGE_CHART_DATA key=type item=value}
<span data-type="storage-{$type}" style="width:{$value/$STORAGE_TOTAL*100}%">
<p>{round($value/$STORAGE_TOTAL*100)}%</p>
</span>
{/foreach}
</div>
<div class="storage-tooltips">
{foreach from=$STORAGE_CHART_DATA key=type item=value}
<p id="storage-{$type}" class="tooltip"><b>{$type}</b> : {$value/1000} MB</p>
{/foreach}
</div>

View File

@@ -547,7 +547,7 @@ FORM.properties SPAN.property {
/* Dashboard */
.intro-page-container {
display: grid;
grid-template-columns: 41% 44%;
grid-template-columns: 50% 49%;
}
.stat-boxes {
@@ -590,10 +590,6 @@ a.stat-box:hover {
color:#777;
}
.intro-charts {
width: 48vw;
}
.chart-title {
font-size: 18px;
text-align: left;
@@ -614,8 +610,8 @@ a.stat-box:hover {
font-weight: bold;
font-size: 14px;
display: grid;
grid-template-columns: repeat(8, 6vw) ;
grid-template-rows: repeat(4, 6vw);
grid-template-columns: repeat(8, 5vw) ;
grid-template-rows: repeat(4, 5vw);
}
.activity-chart .row-legend,.activity-chart .col-legend {
@@ -631,7 +627,7 @@ a.stat-box:hover {
}
.activity-chart .col-legend {
line-height: 6vw;
line-height: 5vw;
}
.activity-chart .row-legend:after {
@@ -640,7 +636,7 @@ a.stat-box:hover {
opacity: 0.05;
position: absolute;
width: 700%;
transform: translate(6vw,3vw);
transform: translate(6vw,2.5vw);
}
.activity-chart .col-legend .line-vertical {
@@ -670,29 +666,87 @@ a.stat-box:hover {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: ease 0.2s;
}
.activity-chart span p {
.intro-charts .tooltip {
position: absolute;
display: none;
opacity: 0;
z-index: 102;
font-size: 12px;
font-weight: normal;
background-color: white;
padding: 5px;
width: 150px;
padding: 10px;
box-shadow: 0px 0px 5px #acacac;
border-radius: 5px;
transform : translate(-50%, 5vw);
border-radius: 10px;
margin: 0px;
transition: ease 0.2s;
left: 50%;
}
.activity-chart span p::after {
.intro-charts .tooltip .tooltip-header {
margin-bottom: 10px;
display: flex;
justify-content: space-between;
font-size: 14px;
}
.intro-charts .tooltip .tooltip-header span {
margin: 0px 5px
}
.intro-charts .tooltip .tooltip-title {
font-weight: bold;
color: #3b3b3b;
}
.intro-charts .tooltip .tooltip-date {
font-style: italic;
}
.intro-charts .tooltip span:before {
width: 1.2em;
font-size: 15px;
}
.intro-charts .tooltip .tooltip-details {
display: flex;
align-items: flex-start;
}
.intro-charts .tooltip .tooltip-details-cont {
display: flex;
flex-direction: column;
align-items: flex-start;
margin: 0px 3px;
}
.intro-charts .tooltip .tooltip-details-title {
font-weight: bold;
padding: 0px 5px;
margin-bottom: 8px;
border-radius: 15px;
background: none !important;
}
.intro-charts .tooltip .tooltip-detail {
margin: 1px;
padding-left: calc(50% - 20px);
}
.activity-chart .tooltip {
left: 50%;
top:45%
}
.intro-charts .tooltip span{
display: inline;
white-space: nowrap;
}
.intro-charts .tooltip::after {
content: " ";
position: absolute;
bottom: 100%; /* At the bottom of the tooltip */
bottom: 100%;
left: 51%;
margin-left: -5px;
border-width: 5px;
@@ -704,8 +758,8 @@ a.stat-box:hover {
padding: 0.5vw;
}
.activity-chart span div:hover + p{
display: block;
.activity-chart span div:hover + .tooltip, .intro-charts .tooltip:hover{
display: inline-grid;
opacity: 1;
}
@@ -735,6 +789,10 @@ a.stat-box:hover {
background-color: #e8e8e8;
}
.storage-tooltips {
position: relative;
}
.storage-chart span{
opacity: 0.7;
transition: ease 0.2s;
@@ -747,12 +805,18 @@ a.stat-box:hover {
opacity: 0;
line-height: 0;
transition: ease 0.2s;
white-space: nowrap;
}
.storage-chart span:hover{
opacity: 1;
}
.storage-chart span:hover .tooltip {
opacity: 1;
display: block;
}
.storage-chart span:hover p{
opacity: 0.4;
}

View File

@@ -236,15 +236,19 @@ a.stat-box:hover {
color: #777;
}
.activity-chart span p {
.intro-charts .tooltip {
background-color: #333333;
box-shadow: none;
}
.activity-chart span p::after {
.intro-charts .tooltip::after {
border-color: transparent transparent #333333 transparent;
}
.intro-charts .tooltip .tooltip-details-title, .intro-charts .tooltip-title {
color:#aeaeae !important;
}
/* hacks */
* html[lang="en"] body .content h2 , *+html[lang="en"] body .content h2 { text-transform:capitalize; } /* IE */
*+html .bigtext { left: 70px; }

View File

@@ -696,6 +696,9 @@ $conf['ws_max_users_per_page'] = 1000;
// Display a link to subscribe to Piwigo Announcements Newsletter
$conf['show_newsletter_subscription'] = true;
// Number Weeks displayed on activity chart on the dashboard
$conf['dashboard_activity_nb_weeks'] = 4;
// +-----------------------------------------------------------------------+
// | Filter |
// +-----------------------------------------------------------------------+