export type Annee = Record<string, { t: number[]; y: number[]; i: number }> export type Sample = { hourly: { x: string[]; y: number[] } daily: { x: string[]; y: number[] } weekly: { x: string[]; y: number[] } } export function sample( min_t: number, max_t: number, annee: Annee, somme: Sample, soleil: Sample ): { auto: number; totalProd: number; totalConso: number } export function sample( min_t: number, max_t: number, annee: Annee, somme: Sample ): undefined export function sample( min_t: number, max_t: number, annee: Annee, somme: Sample, soleil?: Sample ): undefined | { auto: number; totalProd: number; totalConso: number } { let auto = 0 let totalProd = 0 let totalConso = 0 somme.hourly = { x: [], y: [] } somme.daily = { x: [], y: [] } somme.weekly = { x: [], y: [] } let i = 0 for (let [_, r] of Object.entries(annee)) { r.i = 0 } for (let t = min_t; t < max_t; t += 3600) { let tt = new Date(t * 1000) let tds = tt.toLocaleDateString() let tts = tt.toLocaleString() let y = 0 for (let [_, r] of Object.entries(annee)) { // Les profils Enedis sont échantillonnés à la // demi-heure, il faut ajouter deux points consécutifs while (r.i < r.t.length && r.t[r.i] < t + 3600) { if (!isNaN(r.y[r.i])) y += r.y[r.i] r.i += 1 } } somme.hourly.x.push(tts) somme.hourly.y.push(y) if ((t - min_t) % (24 * 3600) == 0) { if ((t - min_t) % (24 * 7 * 3600) == 0) { somme.weekly.x.push(tds) somme.weekly.y.push(y) } else { somme.weekly.y[somme.weekly.y.length - 1] += y } somme.daily.x.push(tds) somme.daily.y.push(y) } else { somme.daily.y[somme.daily.y.length - 1] += y somme.weekly.y[somme.weekly.y.length - 1] += y } totalConso += y if (soleil) { totalProd += soleil.hourly.y[i] auto += Math.min(y, soleil.hourly.y[i]) } i += 1 } if (soleil) { return { auto, totalProd, totalConso, } } } export type PlotSample = { x: (number | string)[] y: number[] bucket: number } export function chooseScale(s: Sample & PlotSample, w?: number) { console.log('chooseScale', w) // ww: nombre d'échantillons bruts à afficher let ww = w || s.hourly.x.length let bbox = (<SVGGraphicsElement | undefined>( document.getElementsByClassName('bglayer')[0] ))?.getBBox() let width = (bbox?.width || 100) / 3 console.log(bbox?.width) if (ww <= width) { s.x = s.hourly.x s.y = s.hourly.y s.bucket = 1 } else if (ww / 24 <= width) { s.x = s.daily.x s.y = s.daily.y s.bucket = 24 } else { s.x = s.weekly.x s.y = s.weekly.y s.bucket = 24 * 7 } } export function relayout( event: any, plot: HTMLElement, Plotly: any, layout: any, has_plot: { has_plot: boolean }, soleil: Sample & PlotSample, somme: Sample & PlotSample ) { console.log('relayout') if (event.bucket) { return false } let w = event['xaxis.range[1]'] - Math.max(0, event['xaxis.range[0]']) let layout_ = JSON.parse(JSON.stringify(layout)) if (!plot) { return false } if (isNaN(w)) { chooseScale(soleil) chooseScale(somme) layout_.xaxis.autorange = true layout_.yaxis.autorange = true event.bucket = soleil.bucket } else { let sb = soleil.bucket if (event.bucket) { w *= event.bucket } else { w *= soleil.bucket } chooseScale(soleil, w) chooseScale(somme, w) let sb_ = soleil.bucket event['xaxis.range[0]'] *= sb / sb_ event['xaxis.range[1]'] *= sb / sb_ event.bucket = soleil.bucket layout_.xaxis.range = [event['xaxis.range[0]'], event['xaxis.range[1]']] let unite: string if (soleil.bucket == 24) { unite = 'kWh/jour' } else if (soleil.bucket == 24 * 7) { unite = 'kWh/semaine' } else { unite = 'kWh' } layout_.yaxis.title.text = unite layout_.yaxis.autorange = true layout_.yaxis.fixedrange = false } if (has_plot.has_plot) { Plotly!.update(plot, [soleil, somme], layout_) } else { Plotly!.newPlot(plot, [soleil, somme], layout_, { responsive: true, }) //@ts-ignore plot.on('plotly_relayout', (event: any) => relayout(event, plot, Plotly, layout, has_plot, soleil, somme) ) has_plot.has_plot = true } }