git ssb

16+

Dominic / patchbay



Commit bc574122903c7ef4a0abf0fb4918a12a4e96a977

/netowkr: minimal working graph of last days gossip

mixmix committed on 12/1/2018, 8:33:18 AM
Parent: 7b91ebea2f9f89a207555eda47a8779b3e83f734

Files changed

app/page/network.jsadded
package-lock.jsonchanged
package.jsonchanged
router/sync/routes.jschanged
app/page/network.jsView
@@ -1,0 +1,202 @@
1 +const nest = require('depnest')
2 +const { h, Value, Dict, onceTrue, computed, watchAll, throttle } = require('mutant')
3 +const Chart = require('chart.js')
4 +const pull = require('pull-stream')
5 +
6 +const MINUTE = 60 * 1000
7 +const DAY = 24 * 60 * MINUTE
8 +
9 +const GRAPH_Y_STEP = 50
10 +const GRAPH_Y_MIN = 100
11 +
12 +exports.gives = nest({
13 + 'app.html.menuItem': true,
14 + 'app.page.network': true
15 +})
16 +
17 +exports.needs = nest({
18 + 'sbot.obs.connection': 'first'
19 +})
20 +
21 +exports.create = function (api) {
22 + return nest({
23 + 'app.html.menuItem': menuItem,
24 + 'app.page.network': networkPage
25 + })
26 +
27 + function menuItem () {
28 + return h('a', {
29 + 'ev-click': () => api.app.sync.goTo({ page: 'network' })
30 + }, '/network')
31 + }
32 +
33 + function networkPage (location) {
34 + const minsPerStep = 5
35 +
36 + const data = Dict()
37 + onceTrue(api.sbot.obs.connection, server => {
38 + getData({ data, server, minsPerStep })
39 + })
40 +
41 + const latest = Value(toTimeBlock(Date.now(), minsPerStep))
42 + // start of the most recent bar
43 + setInterval(() => {
44 + console.log('boop')
45 + latest.set(toTimeBlock(Date.now(), minsPerStep))
46 + }, 2 * MINUTE)
47 +
48 + const range = computed([latest], (latest) => {
49 + return {
50 + upper: latest + minsPerStep * MINUTE,
51 + lower: latest + minsPerStep * MINUTE - DAY
52 + }
53 + })
54 +
55 + //
56 +
57 + const canvas = h('canvas', { height: 300, width: 1200, style: { height: '300px', width: '1200px' } })
58 + const page = h('NetworkPage', { title: '/network' }, [
59 + h('div.container', [
60 + h('h1', 'Network'),
61 + canvas
62 + ])
63 + ])
64 +
65 + initialiseChart({ canvas, data, range })
66 +
67 + return page
68 + }
69 +}
70 +
71 +function getData ({ data, server, minsPerStep }) {
72 + const query = [
73 + {
74 + $filter: {
75 + timestamp: { $gte: toTimeBlock(Date.now(), minsPerStep) + minsPerStep * MINUTE - DAY }
76 + }
77 + }, {
78 + $map: {
79 + ts: ['timestamp']
80 + }
81 + }
82 + ]
83 +
84 + pull(
85 + server.query.read({ query, live: true }),
86 + pull.filter(m => !m.sync),
87 + pull.map(m => toTimeBlock(m.ts, minsPerStep)),
88 + pull.drain(ts => {
89 + if (data.has(ts)) data.put(ts, data.get(ts) + 1)
90 + else data.put(ts, 1)
91 + })
92 + )
93 +}
94 +
95 +function initialiseChart ({ canvas, data, range }) {
96 + var chart = new Chart(canvas.getContext('2d'), chartConfig(range))
97 +
98 + const chartData = computed([throttle(data, 300), range], (data, range) => {
99 + return Object.keys(data)
100 + .filter(ts => ts >= range.lower && ts < range.upper)
101 + .map(ts => {
102 + return {
103 + t: Number(ts), // NOTE - might need to offset by a half-step ?
104 + y: data[ts]
105 + }
106 + })
107 + })
108 + chartData(data => {
109 + chart.data.datasets[0].data = data
110 + chart.update()
111 + })
112 +
113 + // Scales the height of the graph (to the visible data)!
114 + watchAll([chartData, range], (chartData, range) => {
115 + const { lower, upper } = range
116 + const slice = chartData
117 + .filter(d => d.t >= lower && d.t < upper) // unnecessary ??
118 + .map(d => d.y)
119 + .sort((a, b) => a > b ? -1 : +1)
120 +
121 + var h = slice[0]
122 + if (!h || h < GRAPH_Y_MIN) h = GRAPH_Y_MIN // min-height
123 + else h = h + (GRAPH_Y_STEP - h % GRAPH_Y_STEP) // round height to multiples of GRAPH_Y_STEP
124 +
125 + chart.options.scales.yAxes[0].ticks.max = h
126 +
127 + chart.update()
128 + })
129 +
130 + // Update the x-axes bounds of the graph!
131 + range(range => {
132 + const { lower, upper } = range
133 +
134 + chart.options.scales.xAxes[0].time.min = lower
135 + chart.options.scales.xAxes[0].time.max = upper
136 +
137 + chart.update()
138 + })
139 +}
140 +
141 +// ///// HELPERS /////
142 +
143 +function toTimeBlock (ts, minsPerStep) {
144 + return Math.floor(ts / (minsPerStep * MINUTE)) * (minsPerStep * MINUTE)
145 +}
146 +
147 +function chartConfig ({ lower, upper }) {
148 + const barColor = 'hsla(215, 57%, 60%, 1)'
149 +
150 + return {
151 + type: 'bar',
152 + data: {
153 + datasets: [{
154 + backgroundColor: barColor,
155 + borderColor: barColor,
156 + data: []
157 + }]
158 + },
159 + options: {
160 + legend: {
161 + display: false
162 + },
163 + scales: {
164 + xAxes: [{
165 + type: 'time',
166 + distribution: 'linear',
167 + time: {
168 + // unit: 'day',
169 + // min: lower,
170 + // max: upper,
171 + // tooltipFormat: 'MMMM D',
172 + // stepSize: 7
173 + unit: 'minute',
174 + min: lower,
175 + max: upper,
176 + tooltipFormat: 'HH:mm',
177 + stepSize: 240
178 + },
179 + bounds: 'ticks',
180 + ticks: {
181 + // maxTicksLimit: 4 // already disabled
182 + },
183 + gridLines: {
184 + display: false
185 + },
186 + // maxBarThickness: 2
187 + }],
188 +
189 + yAxes: [{
190 + ticks: {
191 + min: 0,
192 + stepSize: GRAPH_Y_STEP,
193 + suggestedMax: GRAPH_Y_MIN
194 + }
195 + }]
196 + },
197 + animation: {
198 + // duration: 300
199 + }
200 + }
201 + }
202 +}
package-lock.jsonView
The diff is too large to show. Use a local git client to view these changes.
Old file size: 382421 bytes
New file size: 383816 bytes
package.jsonView
@@ -43,8 +43,9 @@
4343 },
4444 "homepage": "https://github.com/ssbc/patchbay#readme",
4545 "dependencies": {
4646 "bulk-require": "^1.0.1",
47 + "chart.js": "^2.7.3",
4748 "cross-script": "^1.0.5",
4849 "dataurl-": "^0.1.0",
4950 "depject": "^4.1.1",
5051 "depnest": "^1.3.0",
router/sync/routes.jsView
@@ -10,8 +10,9 @@
1010 'blogs': 'first',
1111 'errors': 'first',
1212 'channel': 'first',
1313 'imageSearch': 'first',
14 + 'network': 'first',
1415 'notifications': 'first',
1516 'posts': 'first',
1617 'postRank': 'first',
1718 'private': 'first',
@@ -36,8 +37,9 @@
3637 [ loc => loc.page === 'blogs', pages.blogs ],
3738 [ loc => loc.page === 'calendar', pages.calendar ],
3839 [ loc => loc.page === 'errors', pages.errors ],
3940 [ loc => loc.page === 'imageSearch', pages.imageSearch ],
41 + [ loc => loc.page === 'network', pages.network ],
4042 [ loc => loc.page === 'notifications', pages.notifications ],
4143 [ loc => loc.page === 'posts', pages.posts ],
4244 [ loc => loc.page === 'postRank', pages.postRank ],
4345 [ loc => loc.page === 'private', pages.private ],

Built with git-ssb-web