Merge branch 'timeline_multi_monitor'

This commit is contained in:
Isaac Connor 2022-02-11 18:08:41 -05:00
commit 0e2f2cf572
8 changed files with 82 additions and 47 deletions

View File

@ -5,6 +5,7 @@ web/api/lib
web/includes/csrf/ web/includes/csrf/
web/js/videojs.zoomrotate.js web/js/videojs.zoomrotate.js
web/skins/classic/js/bootstrap-4.5.0.js web/skins/classic/js/bootstrap-4.5.0.js
web/skins/classic/js/bootstrap.bundle.min.js
web/skins/classic/js/chosen web/skins/classic/js/chosen
web/skins/classic/js/dateTimePicker web/skins/classic/js/dateTimePicker
web/skins/classic/js/jquery-*.js web/skins/classic/js/jquery-*.js

View File

@ -387,6 +387,7 @@ function getFrameImage() {
$sql = 'SELECT * FROM Frames WHERE EventId = ? AND FrameId = ?'; $sql = 'SELECT * FROM Frames WHERE EventId = ? AND FrameId = ?';
if ( !($frame = dbFetchOne($sql, NULL, array($eventId, $frameId))) ) { if ( !($frame = dbFetchOne($sql, NULL, array($eventId, $frameId))) ) {
ZM\Error("Frame not found for event $eventId frame $frameId");
$frame = array(); $frame = array();
$frame['EventId'] = $eventId; $frame['EventId'] = $eventId;
$frame['FrameId'] = $frameId; $frame['FrameId'] = $frameId;

View File

@ -36,9 +36,17 @@
#topPanel { #topPanel {
position: relative; position: relative;
height: 220px; min-height: 220px;
margin: 4px auto 6px; margin: 4px auto 6px;
} }
#topPanel:after {
content: ".";
display: block;
height: 0;
font-size: 0;
clear: both;
visibility: hidden;
}
#topPanel .imagePanel { #topPanel .imagePanel {
text-align: right; text-align: right;
@ -87,6 +95,7 @@
} }
#topPanel #navPanel { #topPanel #navPanel {
float: left;
width: 100%; width: 100%;
height: 70px; height: 70px;
margin: 4px auto; margin: 4px auto;

View File

@ -8,7 +8,9 @@
.chartSize { .chartSize {
height: <?php echo $chart['height'] ?>px; /*
min-height: <?php echo $chart['height'] ?>px;
*/
} }
.graphSize { .graphSize {

View File

@ -1 +1 @@
bootstrap.min.js bootstrap-4.5.0.min.js

View File

@ -1,4 +1,3 @@
var events = {};
function showEvent(e) { function showEvent(e) {
var eid = e.getAttribute('data-event-id'); var eid = e.getAttribute('data-event-id');
@ -33,34 +32,31 @@ function showEventDetail(eventHtml) {
function eventDataResponse(respObj, respText) { function eventDataResponse(respObj, respText) {
var zm_event = respObj.event; var zm_event = respObj.event;
if ( !zm_event ) { if (!zm_event) {
console.log('Null event'); console.log('Null event');
return; return;
} }
events[zm_event.Id] = zm_event; events[zm_event.Id] = zm_event;
if ( respObj.loopback ) { if (respObj.loopback) {
requestFrameData(zm_event.Id, respObj.loopback); requestFrameData(zm_event.Id, respObj.loopback);
} }
} }
function frameDataResponse( respObj, respText ) { function frameDataResponse(respObj, respText) {
var frame = respObj.frameimage; var frame = respObj.frameimage;
if ( !frame.FrameId ) { if (!frame.FrameId) {
console.log('Null frame'); console.log('Null frame');
return; return;
} }
var zm_event = events[frame.EventId]; var zm_event = events[frame.EventId];
if ( !zm_event ) { if (!zm_event) {
console.error('No event '+frame.eventId+' found'); console.error('No event '+frame.eventId+' found');
return; return;
} }
if ( !zm_event['frames'] ) { if (!zm_event['frames']) {
console.log('No frames data in event response');
console.log(zm_event);
console.log(respObj);
zm_event['frames'] = {}; zm_event['frames'] = {};
} }
@ -71,15 +67,14 @@ function frameDataResponse( respObj, respText ) {
} }
function showEventData(zm_event, frameId) { function showEventData(zm_event, frameId) {
if ( zm_event ) { if (zm_event) {
if ( zm_event['frames'] ) { if (zm_event['frames']) {
if ( zm_event['frames'][frameId] ) { if (zm_event['frames'][frameId]) {
$('instruction').addClass('hidden'); $j('#instruction').hide();
eventData = $('eventData'+zm_event.MonitorId); eventData = $j('#eventData'+zm_event.MonitorId);
eventData.empty(); eventData.html(zm_event['frames'][frameId]['html']);
eventData.adopt(zm_event['frames'][frameId]['html']); eventData.show();
eventData.removeClass('hidden'); var imagePath = 'index.php?view=image&eid='+zm_event.Id+'&fid='+frameId;
var imagePath = 'index.php?view=image&eid='+eventId+'&fid='+frameId;
loadEventImage(imagePath, zm_event, frameId); loadEventImage(imagePath, zm_event, frameId);
return; return;
} else { } else {
@ -87,6 +82,7 @@ function showEventData(zm_event, frameId) {
} }
} else { } else {
console.log('No frames'); console.log('No frames');
requestFrameData(zm_event.Id, frameId);
} }
} else { } else {
console.log('No event'); console.log('No event');
@ -105,10 +101,10 @@ function frameQuery(data) {
.fail(logAjaxFail); .fail(logAjaxFail);
} }
function requestFrameData( eventId, frameId ) { function requestFrameData(eventId, frameId) {
var data = {}; var data = {};
if ( !events[eventId] ) { if (!events[eventId]) {
data.id = eventId; data.id = eventId;
data.loopback = frameId; data.loopback = frameId;
eventQuery(data); eventQuery(data);
@ -121,26 +117,36 @@ function requestFrameData( eventId, frameId ) {
function previewEvent(slot) { function previewEvent(slot) {
eventId = slot.getAttribute('data-event-id'); eventId = slot.getAttribute('data-event-id');
frameId = slot.getAttribute('data-frame-id'); frameId = slot.getAttribute('data-frame-id');
if ( events[eventId] && events[eventId]['frames'] && events[eventId]['frames'][frameId] ) { if (events[eventId] && events[eventId]['frames'] && events[eventId]['frames'][frameId]) {
showEventData(eventId, frameId); showEventData(events[eventId], frameId);
} else { } else {
requestFrameData(eventId, frameId); requestFrameData(eventId, frameId);
} }
} }
function loadEventImage( imagePath, zm_event, fid ) { function loadEventImage(imagePath, zm_event, fid) {
var imageSrc = $('imageSrc'+zm_event.MonitorId); if (!zm_event) {
console.log("No event object passed to loadEventImage");
return;
}
const imageSrc = $j('#imageSrc'+zm_event.MonitorId);
imageSrc.show(); imageSrc.show();
imageSrc.setProperty('src', imagePath); imageSrc.attr('src', imagePath);
imageSrc.setAttribute('data-event-id', zm_event.Id); imageSrc.attr('data-event-id', zm_event.Id);
imageSrc.setAttribute('data-frame-id', fid); imageSrc.attr('data-frame-id', fid);
imageSrc.onclick=window['showEvent'].bind(imageSrc, imageSrc); imageSrc.off('click');
imageSrc.on('click', function() {
showEvent(this);
});
var eventData = $('eventData'.zm_event.MonitorId); var eventData = $j('#eventData'+zm_event.MonitorId);
if ( eventData ) { if ( eventData.length ) {
eventData.removeEvent('click'); eventData.off('click');
eventData.addEvent('click', showEvent.pass()); eventData.on('click', function() {
showEvent(this);
});
} else { } else {
console.log("No eventdata area found for monitor " + zm_event.MonitorId); console.log("No eventdata area found for monitor " + zm_event.MonitorId);
} }
@ -204,6 +210,11 @@ function initPage() {
window.location.assign('?view=events'+filterQuery); window.location.assign('?view=events'+filterQuery);
}); });
for (const mid in monitors) {
const monitor = monitors[mid];
showEventData(events[monitor.FirstEventId], 1);
}
// Bind the data-on-click attributes associated with a div // Bind the data-on-click attributes associated with a div
divDataOnClick(); divDataOnClick();
} }

View File

@ -6,18 +6,28 @@
global $maxTime; global $maxTime;
global $range; global $range;
global $majXScale; global $majXScale;
global $monEventSlots;
global $monFrameSlots;
?> ?>
var filterQuery = '<?php echo validJsStr($filterQuery) ?>'; var filterQuery = '<?php echo validJsStr($filterQuery) ?>';
var events = {};
<?php <?php
//ZM\Debug(print_r($monEventSlots, true));
//ZM\Debug(print_r($monFrameSlots, true));
$jsMonitors = array(); $jsMonitors = array();
$fields = array('Name', 'LabelFormat', 'SaveJPEGs', 'VideoWriter'); $fields = array('Name', 'LabelFormat', 'SaveJPEGs', 'VideoWriter');
foreach ( $monitors as $monitor ) { foreach ($monitors as $monitor) {
$jsMonitor = array(); $jsMonitor = array();
foreach ($fields as $field) { foreach ($fields as $field) {
$jsMonitor[$field] = $monitor->$field(); $jsMonitor[$field] = $monitor->$field();
} }
$firstEvent = reset($monEventSlots[$monitor->Id()])['event'];
$jsMonitor['FirstEventId'] = $firstEvent['Id'];
echo 'events['.$firstEvent['Id'].']='.json_encode($firstEvent).';'.PHP_EOL;
$jsMonitors[$monitor->Id()] = $jsMonitor; $jsMonitors[$monitor->Id()] = $jsMonitor;
} }
?> ?>
@ -30,3 +40,4 @@ var midTime = '<?php echo $midTime?>';
var maxTime = '<?php echo $maxTime?>'; var maxTime = '<?php echo $maxTime?>';
var range = '<?php echo $range?>'; var range = '<?php echo $range?>';
var zoomout_range = '<?php (int)($range*$majXScale['zoomout']) ?>'; var zoomout_range = '<?php (int)($range*$majXScale['zoomout']) ?>';

View File

@ -17,12 +17,12 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// //
if ( !canView('Events') ) { if (!canView('Events')) {
$view = 'error'; $view = 'error';
return; return;
} }
foreach ( getSkinIncludes('includes/timeline_functions.php') as $includeFile ) foreach (getSkinIncludes('includes/timeline_functions.php') as $includeFile)
require_once $includeFile; require_once $includeFile;
// //
@ -313,7 +313,7 @@ if ( !$events_result ) {
$max_aspect_ratio = 0; $max_aspect_ratio = 0;
while( $event = $events_result->fetch(PDO::FETCH_ASSOC) ) { while ($event = $events_result->fetch(PDO::FETCH_ASSOC)) {
if ( !isset($monitors[$event['MonitorId']]) ) { if ( !isset($monitors[$event['MonitorId']]) ) {
$monitor = $monitors[$event['MonitorId']] = ZM\Monitor::find_one(array('Id'=>$event['MonitorId'])); $monitor = $monitors[$event['MonitorId']] = ZM\Monitor::find_one(array('Id'=>$event['MonitorId']));
$monEventSlots[$event['MonitorId']] = array(); $monEventSlots[$event['MonitorId']] = array();
@ -361,7 +361,7 @@ while( $event = $events_result->fetch(PDO::FETCH_ASSOC) ) {
$i = $startIndex; $i = $startIndex;
if ( !isset($currFrameSlots[$i]) ) { if ( !isset($currFrameSlots[$i]) ) {
$currFrameSlots[$i] = array('count'=>1, 'value'=>$event['MaxScore'], 'event'=>$event, 'frame'=>$frame); $currFrameSlots[$i] = array('count'=>1, 'value'=>$event['MaxScore'], 'event'=>$event, 'frame'=>$frame, 'id'=>$frame['FrameId']);
} else { } else {
$currFrameSlots[$i]['count']++; $currFrameSlots[$i]['count']++;
if ( $event['MaxScore'] > $currFrameSlots[$i]['value'] ) { if ( $event['MaxScore'] > $currFrameSlots[$i]['value'] ) {
@ -434,10 +434,10 @@ $majYScale = getYScale(
$chart['grid']['y']['major']['max']); $chart['grid']['y']['major']['max']);
// Optimise boxes // Optimise boxes
foreach( array_keys($monEventSlots) as $monitorId ) { foreach (array_keys($monEventSlots) as $monitorId) {
unset( $currEventSlots ); unset($currEventSlots);
$currEventSlots = &$monEventSlots[$monitorId]; $currEventSlots = &$monEventSlots[$monitorId];
for ( $i = 0; $i < $chart['graph']['width']; $i++ ) { for ($i = 0; $i < $chart['graph']['width']; $i++) {
if ( isset($currEventSlots[$i]) ) { if ( isset($currEventSlots[$i]) ) {
if ( isset($currSlot) ) { if ( isset($currSlot) ) {
if ( $currSlot['event']['Id'] == $currEventSlots[$i]['event']['Id'] ) { if ( $currSlot['event']['Id'] == $currEventSlots[$i]['event']['Id'] ) {
@ -692,13 +692,13 @@ xhtmlHeaders(__FILE__, translate('Timeline'));
<?php <?php
foreach ( $monitors as $monitor ) { foreach ( $monitors as $monitor ) {
?> ?>
<div class="monitorPanel" style="width:<?php echo 100/count($monitors); ?>%;float:left;"> <div class="monitorPanel" style="width:<?php echo 100/count($monitors); ?>%; float:left;">
<div class="imagePanel"> <div class="imagePanel"<?php echo count($monitors)==1?' style="width: 50%; float: left;"' :''?>>
<div class="imageHeight image"> <div class="imageHeight image">
<img id="imageSrc<?php echo $monitor->Id() ?>" class="imageWidth" src="graphics/transparent.png" alt="<?php echo translate('ViewEvent') ?>" title="<?php echo translate('ViewEvent') ?>"/> <img id="imageSrc<?php echo $monitor->Id() ?>" class="imageWidth" src="graphics/transparent.png" alt="<?php echo translate('ViewEvent') ?>" title="<?php echo translate('ViewEvent') ?>"/>
</div> </div>
</div> </div>
<div id="dataPanel<?php echo $monitor->Id() ?>"> <div id="dataPanel<?php echo $monitor->Id() ?>" class="dataPanel"<?php echo count($monitors)==1?' style="width: 50%; float: left;"' :''?>>
<div id="textPanel<?php echo $monitor->Id() ?>"> <div id="textPanel<?php echo $monitor->Id() ?>">
<div id="eventData<?php echo $monitor->Id() ?>"> <div id="eventData<?php echo $monitor->Id() ?>">
</div> </div>