Correlate
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.
'; $streams=db()->query("SELECT s.code,s.label FROM streams s WHERE s.visibility='public' ORDER BY s.label")->fetchAll(); $sel = $_GET['s'] ?? ['wx_temp','ac_impact_activity']; $sel = array_slice(array_filter((array)$sel), 0, 4); $from=$_GET['from']??date('Y-m-d',strtotime('-30 days')); $to=$_GET['to']??date('Y-m-d'); $lag=(int)($_GET['lag']??0); echo ''; $out=[]; $slot=0; foreach($sel as $i=>$code){ if(!$code) continue; $s=stream_by_code($code); if(!$s||!visible($s)) continue; $rows=series($s,$from.' 00:00:00',$to.' 23:59:59'); 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); } $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']]; } if($out){ $tags=''; foreach($out as $o){ $tags.=$o['mode']==='live'?'LIVE DATA ':'PLACEHOLDER DATA '; } echo '