PageSourceSearch

https://spacefarmers.io/assets/controllers/farmers_statistics_cont…0a11b2e1c1cc5cd2bc7fb404ec3140fa08240af5.js

js spacefarmers.io collected 2026-10-07 22:08:03 UTC 12,305 bytes, 390 lines download raw bytes

1import {
2  Controller
3} from "@hotwired/stimulus"
4
5export default class extends Controller {
6  static targets = ["sizeCard"]
7
8  connect() {
9    this.launcherId = document.getElementById('launcher-id').dataset.launcherId;
10    this.chart_size_period = '7d'
11    this.chart_points_period = '7d'
12    this.chart_partials_period = '7d'
13    activeTab('statistics');
14    this.initFarmChart();
15    this.initPointsChart();
16    this.initPartialsChart();
17    convertUTCTime();
18    this.lastPartialHighlight();
19    this.lastCardRefresh = Date.now();
20    this.lastChartRefresh = Date.now();
21    this.cardRefreshInterval = setInterval(() => {
22      if (document.hidden) return;
23      this.refreshCards();
24    }, 300 * 1000);
25    this.chartRefreshInterval = setInterval(() => {
26      if (document.hidden) return;
27      this.refreshCharts();
28    }, 900 * 1000);
29    this.handleVisibilityChange = () => {
30      if (document.hidden) return;
31      const now = Date.now();
32      if (now - this.lastCardRefresh >= 300 * 1000) this.refreshCards();
33      if (now - this.lastChartRefresh >= 900 * 1000) this.refreshCharts();
34    };
35    document.addEventListener('visibilitychange', this.handleVisibilityChange);
36  }
37
38  disconnect() {
39    clearInterval(this.cardRefreshInterval);
40    clearInterval(this.chartRefreshInterval);
41    document.removeEventListener('visibilitychange', this.handleVisibilityChange);
42    window.removeEventListener('farmer:partial', this.newPartial, false);
43  }
44
45  refreshCards() {
46    this.lastCardRefresh = Date.now();
47    fetch(`/farmers/${this.launcherId}/statistics_cards`)
48      .then(response => response.text())
49      .then(html => {
50        const parser = new DOMParser();
51        const doc = parser.parseFromString(html, 'text/html');
52        ['farmer-size-card', 'farmer-points-card', 'farmer-partials-card'].forEach(id => {
53          const source = doc.getElementById(id);
54          const target = document.getElementById(id);
55          if (source && target) {
56            target.innerHTML = source.innerHTML;
57          }
58        });
59        convertUTCTime();
60        this.lastPartialHighlight();
61      });
62  }
63
64  refreshCharts() {
65    this.lastChartRefresh = Date.now();
66    this.getFarmSizeData();
67    this.getFarmPointsData();
68    this.getFarmPartialsData(false);
69  }
70
71  lastPartialHighlight() {
72    if (document.querySelectorAll('.time-to-words').length > 0)
73      timeago.render(document.querySelectorAll('.time-to-words'));
74    window.addEventListener('farmer:partial', this.newPartial, false);
75    document.getElementById('last-partial').addEventListener('animationend', () => {
76      document.getElementById('last-partial').classList.remove('blink-bg');
77    });
78  }
79
80  sizeCardTargetConnected() {
81    convertUTCTime();
82    this.lastPartialHighlight();
83  }
84
85  newPartial(e) {
86    const action = e.detail.action
87    const partial = e.detail.data
88    if (action == 'create') {
89      document.getElementById('last-partial-time').dataset.date = new Date(partial.timestamp * 1000);
90      document.getElementById('last-partial-time').classList.add('utc-time');
91      convertUTCTime();
92      document.getElementById('last-partial-time-ago').setAttribute('datetime', partial.timestamp * 1000);
93      timeago.cancel(document.getElementById('last-partial-time-ago'));
94      timeago.render(document.getElementById('last-partial-time-ago'));
95      document.getElementById('last-partial').classList.add('blink-bg');
96    }
97  }
98
99  initFarmChart() {
100    var chart = document.getElementById('farmChart');
101    var lineChartColor = getChartColorsArray('farmChart');
102    if (lineChartColor) {
103      this.farmChart = new Chart(chart, {
104        type: 'line',
105        data: {
106          datasets: [{
107              label: "Farm size (TiB)",
108              fill: true,
109              lineTension: 0.2,
110              backgroundColor: lineChartColor[0],
111              borderColor: lineChartColor[1],
112              pointRadius: 1,
113              pointHitRadius: 30,
114              data: [],
115              yAxisID: 'TiB'
116            },
117            {
118              label: "Difficulty",
119              fill: false,
120              lineTension: 0.2,
121              backgroundColor: lineChartColor[2],
122              borderColor: lineChartColor[3],
123              pointRadius: 1,
124              pointHitRadius: 30,
125              stepped: true,
126              data: [],
127              yAxisID: 'Difficulty'
128            }
129          ]
130        },
131        options: {
132          maintainAspectRatio: false,
133          scales: {
134            xAxis: {
135              type: 'time',
136              time: {
137                unit: 'day'
138              },
139              parsing: false
140            },
141            TiB: {
142              min: 0,
143              position: 'right',
144              afterSetDimensions: (scale) => {
145                scale.paddingLeft = (window.innerWidth >= 1000 ? 70 : 0)
146              }
147            },
148            Difficulty: {
149              min: 0,
150              position: 'left',
151              grid: {
152                display: false
153              },
154              afterSetDimensions: (scale) => {
155                scale.paddingRight = (window.innerWidth >= 1000 ? 70 : 0)
156              }
157            }
158          },
159          interaction: {
160            intersect: false,
161            mode: 'index',
162          },
163          plugins: {
164            htmlLegend: {
165              // ID of the container to put the legend in
166              containerID: 'farm-size-legend',
167            },
168            legend: {
169              display: false,
170            },
171          },
172        },
173        plugins: [htmlLegendPlugin],
174      });
175    }
176    this.getFarmSizeData();
177  }
178
179  getFarmSizeData() {
180    const launcherId = document.getElementById('launcher-id').dataset.launcherId;
181    const url = '/api/charts/farm_size?launcher_id=' + launcherId + '&period=' + this.chart_size_period;
182    const $this = this
183    axios(url).then(function (response) {
184      $this.farmChart.data.datasets[0].data = response.data;
185      $this.farmChart.update();
186      $this.getFarmDifficultyData();
187    })
188  }
189
190  getFarmDifficultyData() {
191    const launcherId = document.getElementById('launcher-id').dataset.launcherId;
192    var url = '/api/charts/farm_difficulty?launcher_id=' + launcherId + '&period=' + this.chart_size_period;
193    var $this = this
194    axios(url).then(function (response) {
195      $this.farmChart.data.datasets[1].data = response.data;
196      $this.farmChart.update();
197    })
198  }
199
200  initPointsChart() {
201    var chart = document.getElementById('pointsChart');
202    var lineChartColor = getChartColorsArray('pointsChart');
203    if (lineChartColor) {
204      this.pointsChart = new Chart(chart, {
205        type: 'bar',
206        data: {
207          datasets: [{
208            label: "Points",
209            backgroundColor: lineChartColor[1],
210            borderColor: lineChartColor[1],
211            data: [],
212            yAxisID: 'Points'
213          }]
214        },
215        options: {
216          maintainAspectRatio: false,
217          scales: {
218            xAxis: {
219              type: 'time',
220              offset: false,
221              max: nextHour(),
222              time: {
223                unit: 'day'
224              },
225              parsing: false
226            },
227            Points: {
228              min: 0,
229              position: 'right',
230              afterSetDimensions: (scale) => {
231                scale.paddingLeft = (window.innerWidth >= 1000 ? 70 : 0)
232              }
233            },
234            ySpacing: {
235              display: false,
236              afterSetDimensions: (scale) => {
237                scale.paddingRight = (window.innerWidth >= 1000 ? 70 : 0)
238              }
239            },
240          },
241          interaction: {
242            intersect: false,
243            mode: 'index',
244          },
245          plugins: {
246            htmlLegend: {
247              // ID of the container to put the legend in
248              containerID: 'points-legend',
249            },
250            legend: {
251              display: false,
252            },
253          },
254        },
255        plugins: [htmlLegendPlugin],
256      });
257    }
258    this.getFarmPointsData();
259  }
260
261  getFarmPointsData() {
262    const launcherId = document.getElementById('launcher-id').dataset.launcherId;
263    var url = '/api/charts/farm_points?launcher_id=' + launcherId + '&period=' + this.chart_points_period;
264    var $this = this
265    axios(url).then(function (response) {
266      $this.pointsChart.data.datasets[0].data = response.data;
267      $this.pointsChart.update();
268    })
269  }
270
271  toggleFarmSizes() {
272    var elements = document.getElementsByClassName("farm-sizes");
273    Array.from(elements).forEach(function (el) {
274      el.classList.toggle("d-none");
275    });
276  }
277
278  initPartialsChart() {
279    var chart = document.getElementById('partialsChart');
280    var lineChartColor = getChartColorsArray('partialsChart');
281    if (lineChartColor) {
282      this.partialsChart = new Chart(chart, {
283        type: 'bar',
284        data: {
285          datasets: []
286        },
287        options: {
288          maintainAspectRatio: false,
289          scales: {
290            xAxis: {
291              stacked: true,
292              type: 'time',
293              offset: false,
294              max: nextHour(),
295              time: {
296                unit: 'day'
297              },
298              parsing: false
299            },
300            y: {
301              position: 'right',
302              stacked: true,
303              afterSetDimensions: (scale) => {
304                scale.paddingLeft = (window.innerWidth >= 1000 ? 70 : 0)
305              }
306            },
307            ySpacing: {
308              display: false,
309              afterSetDimensions: (scale) => {
310                scale.paddingRight = (window.innerWidth >= 1000 ? 70 : 0)
311              }
312            },
313          },
314          interaction: {
315            intersect: false,
316            mode: 'index',
317          },
318          plugins: {
319            htmlLegend: {
320              // ID of the container to put the legend in
321              containerID: 'partials-legend',
322            },
323            legend: {
324              display: false,
325            },
326          },
327        },
328        plugins: [htmlLegendPlugin],
329      });
330    }
331    this.getFarmPartialsData();
332  }
333
334  getFarmPartialsData(animate = true) {
335    const launcherId = document.getElementById('launcher-id').dataset.launcherId;
336    var url = '/api/charts/farm_partials?launcher_id=' + launcherId + '&period=' + this.chart_partials_period;
337    var $this = this
338    axios(url).then(function (response) {
339      $this.partialsChart.data.datasets = [];
340      response.data.map(row => {
341        var data = [];
342        $this.partialsChart.data.datasets.push({
343          label: row.status_text,
344          backgroundColor: row.color,
345          data: row.data,
346        });
347      });
348      $this.partialsChart.update(animate ? null : 'none');
349    })
350  }
351
352  changeFarmChartPeriod(event) {
353    var elements = document.getElementsByClassName("farm-chart-period");
354    elements && Array.from(elements).forEach(function (el) {
355      el.classList.remove("btn-primary");
356      el.classList.add("btn-soft-dark");
357    });
358    event.target.classList.remove("btn-soft-dark");
359    event.target.classList.add("btn-primary");
360    var chart = document.getElementById('farmChart');
361    this.chart_size_period = event.params.period
362    this.getFarmSizeData();
363  }
364
365  changePointsChartPeriod(event) {
366    var elements = document.getElementsByClassName("points-chart-period");
367    elements && Array.from(elements).forEach(function (el) {
368      el.classList.remove("btn-primary");
369      el.classList.add("btn-soft-dark");
370    });
371    event.target.classList.remove("btn-soft-dark");
372    event.target.classList.add("btn-primary");
373    var chart = document.getElementById('pointsChart');
374    this.chart_points_period = event.params.period
375    this.getFarmPointsData();
376  }
377
378  changePartialsChartPeriod(event) {
379    var elements = document.getElementsByClassName("partials-chart-period");
380    elements && Array.from(elements).forEach(function (el) {
381      el.classList.remove("btn-primary");
382      el.classList.add("btn-soft-dark");
383    });
384    event.target.classList.remove("btn-soft-dark");
385    event.target.classList.add("btn-primary");
386    var chart = document.getElementById('partialsChart');
387    this.chart_partials_period = event.params.period
388    this.getFarmPartialsData();
389  }
390};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.