Skip to content

Commit d126f34

Browse files
committed
added uploading dataset and drag & drop support
1 parent 63bf62b commit d126f34

File tree

10 files changed

+434
-103
lines changed

10 files changed

+434
-103
lines changed

modules/demo/ssr/graph/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const fastify = require('fastify')();
1919
fastify //
2020
.register(require('./plugins/webrtc'), require('./plugins/graph')(fastify))
2121
.register(require('fastify-static'), {root: require('path').join(__dirname, 'public')})
22-
.get('/', (req, reply) => reply.sendFile('video.html'));
22+
.register(require('./plugins/api'))
23+
.get('/', (req, reply) => reply.sendFile('video.html'))
2324

2425
fastify.listen(8080).then(() => console.log('server ready'));

modules/demo/ssr/graph/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@
2121
"fastify-socket.io": "2.0.0",
2222
"fastify-static": "4.2.3",
2323
"fastify": "3.20.2",
24+
"fastify-multipart": "5.0.2",
25+
"fastify-cors": "6.0.2",
2426
"nanoid": "3.1.25",
2527
"rxjs": "6.6.7",
2628
"shm-typed-array": "0.0.13",
2729
"simple-peer": "9.11.0",
28-
"socket.io": "4.1.3"
30+
"socket.io": "4.1.3",
31+
"glob": "7.2.0"
2932
},
3033
"files": [
3134
"render",
+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
const {graphs, clients} = require('../graph');
2+
const fs = require('fs')
3+
const util = require('util')
4+
const {pipeline} = require('stream')
5+
const pump = util.promisify(pipeline)
6+
var glob = require('glob');
7+
const {Float32Buffer} = require('@rapidsai/cuda');
8+
const {GraphCOO} = require('@rapidsai/cugraph');
9+
const {DataFrame, Uint32} = require('@rapidsai/cudf');
10+
const {loadEdges, loadNodes} = require('../graph/loader');
11+
12+
function readDataFrame(path) {
13+
let df = new DataFrame({});
14+
if (path.indexOf('.csv', path.length - 4) !== -1) {
15+
// csv file
16+
df = DataFrame.readCSV({sources: [path], header: 0, sourceType: 'files'});
17+
18+
} else if (path.indexOf('.parquet', path.length - 8) !== -1) {
19+
// csv file
20+
df = DataFrame.readParquet({sources: [path]});
21+
}
22+
if (df.names.includes('Unnamed: 0')) { df = df.cast({'Unnamed: 0': new Uint32}); }
23+
return df;
24+
}
25+
26+
async function getNodesForGraph(asDeviceMemory, nodes, numNodes) {
27+
let nodesRes = {};
28+
const pos = new Float32Buffer(Array.from(
29+
{length: numNodes * 2},
30+
() => Math.random() * 1000 * (Math.random() < 0.5 ? -1 : 1),
31+
));
32+
33+
if (nodes.x in nodes.dataframe.names) {
34+
nodesRes.nodeXPositions = asDeviceMemory(nodes.dataframe.get(node.x).data);
35+
} else {
36+
nodesRes.nodeXPositions = pos.subarray(0, pos.length / 2);
37+
}
38+
if (nodes.y in nodes.dataframe.names) {
39+
nodesRes.nodeYPositions = asDeviceMemory(nodes.dataframe.get(node.y).data);
40+
} else {
41+
nodesRes.nodeYPositions = pos.subarray(pos.length / 2);
42+
}
43+
if (nodes.dataframe.names.includes(nodes.size)) {
44+
nodesRes.nodeRadius = asDeviceMemory(nodes.dataframe.get(nodes.size).data);
45+
}
46+
if (nodes.dataframe.names.includes(nodes.color)) {
47+
nodesRes.nodeFillColors = asDeviceMemory(nodes.dataframe.get(nodes.color).data);
48+
}
49+
if (nodes.dataframe.names.includes(nodes.id)) {
50+
nodesRes.nodeElementIndices = asDeviceMemory(nodes.dataframe.get(nodes.id).data);
51+
}
52+
return nodesRes;
53+
}
54+
55+
async function getEdgesForGraph(asDeviceMemory, edges) {
56+
let edgesRes = {};
57+
58+
if (edges.dataframe.names.includes(edges.color)) {
59+
edgesRes.edgeColors = asDeviceMemory(edges.dataframe.get(edges.color).data);
60+
}
61+
if (edges.dataframe.names.includes(edges.id)) {
62+
edgesRes.edgeList = asDeviceMemory(edges.dataframe.get(edges.id).data);
63+
}
64+
if (edges.dataframe.names.includes(edges.bundle)) {
65+
edgesRes.edgeBundles = asDeviceMemory(edges.dataframe.get(edges.bundle).data);
66+
}
67+
return edgesRes;
68+
}
69+
70+
module.exports = function(fastify, opts, done) {
71+
fastify.register(require('fastify-multipart'))
72+
fastify.register(require('fastify-cors'),
73+
{
74+
// put your options here
75+
});
76+
77+
// fastify.addHook('preValidation', (request, reply, done) => {
78+
// console.log('this is executed', request);
79+
// done()
80+
// });
81+
82+
async function loadGraph(id, data) {
83+
if (!(id in fastify[graphs])) {
84+
const asDeviceMemory = (buf) => new (buf[Symbol.species])(buf);
85+
const src = data.edges.dataframe.get(data.edges.src);
86+
const dst = data.edges.dataframe.get(data.edges.dst);
87+
const graph = new GraphCOO(src._col, dst._col, {directedEdges: true});
88+
fastify[graphs][id] = {
89+
refCount: 0,
90+
nodes: await getNodesForGraph(asDeviceMemory, data.nodes, graph.numNodes()),
91+
edges: await getEdgesForGraph(asDeviceMemory, data.edges),
92+
graph: graph,
93+
};
94+
}
95+
96+
++fastify[graphs][id].refCount;
97+
98+
return {
99+
gravity: 0.0,
100+
linLogMode: false,
101+
scalingRatio: 5.0,
102+
barnesHutTheta: 0.0,
103+
jitterTolerance: 0.05,
104+
strongGravityMode: false,
105+
outboundAttraction: false,
106+
graph: fastify[graphs][id].graph,
107+
nodes: {
108+
...fastify[graphs][id].nodes,
109+
length: fastify[graphs][id].graph.numNodes(),
110+
},
111+
edges: {
112+
...fastify[graphs][id].edges,
113+
length: fastify[graphs][id].graph.numEdges(),
114+
},
115+
};
116+
}
117+
118+
fastify.get('/getIDValue', async (request, reply) => {
119+
console.log(fastify[clients][request.query.id + ':video']);
120+
reply.send(fastify[clients][request.query.id + ':video'].graph.dataframes[0].numRows);
121+
});
122+
123+
fastify.post('/uploadFile', async function(req, reply) {
124+
const data = await req.file();
125+
126+
const filepath = `${__dirname}/../../data/${data.filename}`;
127+
const target = fs.createWriteStream(filepath);
128+
try {
129+
await pump(data.file, target);
130+
console.log('success');
131+
} catch (err) { console.log(err); }
132+
reply.send()
133+
});
134+
135+
fastify.get('/getFileNames', async (request, reply) => {
136+
if (`${request.query.id}:video` in fastify[clients]) {
137+
glob(`*.{csv,parquet}`,
138+
{cwd: `${__dirname}/../../data/`},
139+
(er, files) => { reply.send(JSON.stringify(files.concat(['defaultExample']))); });
140+
} else {
141+
reply.code(500).send('client handshake not established');
142+
}
143+
});
144+
145+
fastify.get('/loadOnGPU', async (request, reply) => {
146+
const id = `${request.query.id}:video`;
147+
const filePath = `${__dirname}/../../data/`
148+
if (id in fastify[clients]) {
149+
if (fs.existsSync(`${filePath}${request.query.nodes}`) &&
150+
fs.existsSync(`${filePath}${request.query.edges}`)) {
151+
fastify[clients][id].data.nodes.dataframe =
152+
await readDataFrame(`${filePath}${request.query.nodes}`);
153+
154+
fastify[clients][id].data.edges.dataframe =
155+
await readDataFrame(`${filePath}${request.query.edges}`);
156+
} else {
157+
fastify[clients][id].data.nodes.dataframe = await loadNodes();
158+
fastify[clients][id].data.edges.dataframe = await loadEdges();
159+
}
160+
reply.send('successfully loaded in GPU Memory');
161+
}
162+
else {
163+
reply.code(500).send('client handshake not established');
164+
}
165+
})
166+
167+
fastify.get('/fetchDFParameters', async (request, reply) => {
168+
const id = `${request.query.id}:video`;
169+
if (id in fastify[clients]) {
170+
reply.send(JSON.stringify({
171+
nodesParams: fastify[clients][id].data.nodes.dataframe.names.concat([null]),
172+
edgesParams: fastify[clients][id].data.edges.dataframe.names.concat([null])
173+
}));
174+
} else {
175+
reply.code(500).send('client handshake not established');
176+
}
177+
});
178+
179+
fastify.post('/updateRenderColumns', async (request, reply) => {
180+
const id = `${request.body.id}:video`;
181+
if (id in fastify[clients]) {
182+
Object.assign(fastify[clients][id].data.nodes, request.body.nodes);
183+
Object.assign(fastify[clients][id].data.edges, request.body.edges);
184+
fastify[clients][id].graph = await loadGraph('default', fastify[clients][id].data);
185+
} else {
186+
reply.code(500).send('client handshake not established');
187+
}
188+
});
189+
done();
190+
}

0 commit comments

Comments
 (0)