pages/correlate.php
Snapshot 2026.09.17-a2894de (current) · 49 lines · 3,707 bytes · tree · plain text
SHA-256
3da5d4344f22d0ebe89e799801f5cb59e1547bf26f6d5278d4293d9853ca7faa| 1 | <?php |
| 2 | require_once __DIR__.'/../inc/layout.php'; |
| 3 | /* CSV export path runs BEFORE any output */ |
| 4 | if(isset($_GET['csv'])){ |
| 5 | $selE=array_slice(array_filter((array)($_GET['s']??[])),0,4); |
| 6 | $fromE=$_GET['from']??date('Y-m-d',strtotime('-30 days')); $toE=$_GET['to']??date('Y-m-d'); |
| 7 | header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename=correlate.csv'); |
| 8 | $fp=fopen('php://output','w'); fputcsv($fp,['ts','series','value','unit','mode']); |
| 9 | foreach($selE as $codeE){ $sE=stream_by_code($codeE); if(!$sE||!visible($sE)) continue; |
| 10 | foreach(series($sE,$fromE.' 00:00:00',$toE.' 23:59:59') as $d) fputcsv($fp,[$d['ts'],$sE['label'],$d['value'],$sE['unit'],$sE['mode']]); |
| 11 | } exit; |
| 12 | } |
| 13 | page_header('Correlate','correlate'); |
| 14 | echo '<h1>Correlate</h1><div class="exploratory">EXPLORATORY WORKBENCH · nothing here is a finding</div>'; |
| 15 | echo '<p class="lede">Overlay any public streams on one time axis, lag one against another, and export the combined series. Multi-stream overlays are indexed to their own range (single axis, no dual scales); the tooltip carries true values and units.</p>'; |
| 16 | $streams=db()->query("SELECT s.code,s.label FROM streams s WHERE s.visibility='public' ORDER BY s.label")->fetchAll(); |
| 17 | $sel = $_GET['s'] ?? ['wx_temp','ac_impact_activity']; |
| 18 | $sel = array_slice(array_filter((array)$sel), 0, 4); |
| 19 | $from=$_GET['from']??date('Y-m-d',strtotime('-30 days')); $to=$_GET['to']??date('Y-m-d'); |
| 20 | $lag=(int)($_GET['lag']??0); |
| 21 | echo '<form class="controls" method="get"><input type="hidden" name="p" value="correlate">'; |
| 22 | for($i=0;$i<4;$i++){ |
| 23 | echo '<div><label>SERIES '.($i+1).'</label><select name="s[]"><option value="">·</option>'; |
| 24 | foreach($streams as $st){ $on=($sel[$i]??'')===$st['code']?' selected':''; echo '<option value="'.h($st['code']).'"'.$on.'>'.h($st['label']).'</option>'; } |
| 25 | echo '</select></div>'; |
| 26 | } |
| 27 | echo '<div><label>FROM</label><input type="date" name="from" value="'.h($from).'"></div><div><label>TO</label><input type="date" name="to" value="'.h($to).'"></div>'; |
| 28 | echo '<div><label>LAG SERIES 2 (hours): '.$lag.'</label><input type="range" name="lag" min="-72" max="72" value="'.$lag.'" onchange="this.form.submit()"></div>'; |
| 29 | echo '<button>Draw</button> <button class="ghost" name="csv" value="1">Export CSV</button></form>'; |
| 30 | $out=[]; $slot=0; |
| 31 | foreach($sel as $i=>$code){ |
| 32 | if(!$code) continue; $s=stream_by_code($code); if(!$s||!visible($s)) continue; |
| 33 | $rows=series($s,$from.' 00:00:00',$to.' 23:59:59'); |
| 34 | if($i===1 && $lag!==0){ $rows=array_map(function($r)use($lag){$r['ts']=date('Y-m-d H:i:s',strtotime($r['ts'])+$lag*3600);return $r;},$rows); } |
| 35 | $out[]=['label'=>$s['label'].($i===1&&$lag?' (lag '.$lag.'h)':''),'slot'=>$slot++,'data'=>array_map(fn($r)=>[substr($r['ts'],0,16),(float)$r['value']],$rows),'unit'=>$s['unit'],'mode'=>$s['mode']]; |
| 36 | } |
| 37 | if($out){ |
| 38 | $tags=''; foreach($out as $o){ $tags.=$o['mode']==='live'?'<span class="badge badge-live">LIVE DATA</span> ':'<span class="badge badge-ph">PLACEHOLDER DATA</span> '; } |
| 39 | echo '<div class="card"><h3>Overlay '.$tags.'</h3><div class="chart tall" data-chart=\''.h(json_encode(['normalize'=>true,'series'=>$out])).'\'></div></div>'; |
| 40 | } |
| 41 | echo '<h2>Pre-built views</h2><div class="grid cols3">'; |
| 42 | $pre=[['Birds vs construction vs weather','s[]=ac_impact_activity&s[]=cx_machine_days&s[]=wx_wind'], |
| 43 | ['Footfall vs wildlife detections','s[]=ff_paths&s[]=th_detections'], |
| 44 | ['Occupancy vs resource use','s[]=ops_occupancy&s[]=res_energy'], |
| 45 | ['Sky brightness vs installation activity','s[]=sky_mpsas&s[]=grim_sessions']]; |
| 46 | foreach($pre as [$t,$qs]) echo '<div class="card"><h3>'.h($t).'</h3><div class="kv"><a href="index.php?p=correlate&'.$qs.'">open →</a></div></div>'; |
| 47 | echo '</div>'; |
| 48 | page_footer(); |
| 49 | |
Lines can be cited as pages/correlate.php L120-L140, platform code 2026.09.17-a2894de; add #L120-L140 to this page's address to highlight them. Source shown for scrutiny of the research platform. All rights reserved. Not offered as installable software.