Skip to content

Commit

Permalink
refa: get graph as functionnal
Browse files Browse the repository at this point in the history
  • Loading branch information
Myllaume committed Aug 21, 2024
1 parent 5210482 commit cb926a1
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 95 deletions.
3 changes: 2 additions & 1 deletion controllers/modelize.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Report from '../models/report-cli.js';
import { DowloadOnlineCsvFilesError } from '../core/models/errors.js';
import { downloadFile } from '../core/utils/misc.js';
import { tmpdir } from 'node:os';
import getGraph from '../functions/getGraph.js';

async function modelize(options) {
let config = Config.get(Config.configFilePath);
Expand Down Expand Up @@ -108,7 +109,7 @@ async function modelize(options) {
}
}

const graph = Cosmoscope.getGraph(records, config.opts);
const graph = getGraph(records, config);

const { html } = new Template(records, graph, optionsTemplate);

Expand Down
94 changes: 0 additions & 94 deletions core/models/cosmoscope.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,100 +334,6 @@ class Cosmoscope {
return bibliographicRecords;
}

/**
* @param {Record[]} records
* @param {Config.opts} opts
*/

static getGraph(records, opts) {
const graph = new GraphEngine({ multi: true }, opts);

/**
* @param {number} degree Node degree
* @returns {number}
*/

function getNodeSize(degree) {
switch (opts['node_size_method']) {
case 'unique':
return opts['node_size'];
case 'degree':
const compute = scaleLinear()
.domain([minDegree, maxDegree])
.range([opts['node_size_min'], opts['node_size_max']]);

const size = compute(degree);
// round at most two decimals
return Math.round(size * 100) / 100;
}
}

function getLinkShape(linkType) {
const linkTypeConfig = opts.link_types[linkType];
const stroke = linkTypeConfig?.stroke || 'simple';

switch (stroke) {
case 'simple':
return { stroke: stroke, dashInterval: null };

case 'double':
return { stroke: stroke, dashInterval: null };

case 'dash':
return { stroke: stroke, dashInterval: '4, 5' };

case 'dotted':
return { stroke: stroke, dashInterval: '1, 3' };
}

return { stroke: 'simple', dashInterval: null };
}

records.forEach(({ id, title, types, thumbnail, begin, end }) => {
graph.addNode(id, {
label: title,
types,
thumbnail,
begin,
end,
});
});

records.forEach(({ id: nodeId, wikilinks, bibliographicRecords }) => {
wikilinks.forEach(({ target, type }) => {
graph.addEdge(nodeId, target, {
type,
shape: getLinkShape(type),
});
});

bibliographicRecords.forEach(({ target }) => {
if (!graph.hasNode(nodeId) || !graph.hasNode(target)) {
return;
}

return graph.addEdge(nodeId, target, {
type: 'undefined',
shape: getLinkShape('undefined'),
});
});
});

const degrees = graph.nodes().map((node) => graph.degree(node));
const minDegree = Math.min(...degrees);
const maxDegree = Math.max(...degrees);

graph.updateEachNodeAttributes((node, attr) => {
const size = getNodeSize(graph.degree(node));
return {
...attr,
size,
};
});

return graph;
}

/**
* Get the index from which to create new records in the mass
* The index depends on the identifier of the last record created in the mass
Expand Down
109 changes: 109 additions & 0 deletions functions/getGraph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import GraphEngine from 'graphology';
import { scaleLinear } from 'd3';
import Config from '../core/models/config';

/**
* @param {number} degree
* @param {number} minDegree
* @param {number} maxDegree
* @param {Config} config
* @returns {number}
*/

function getNodeSize(degree, minDegree, maxDegree, config) {
switch (config.opts['node_size_method']) {
case 'unique':
return config.opts['node_size'];
case 'degree':
const compute = scaleLinear()
.domain([minDegree, maxDegree])
.range([config.opts['node_size_min'], config.opts['node_size_max']]);

const size = compute(degree);
// round at most two decimals
return Math.round(size * 100) / 100;
}
}

/**
* @param {string} linkType
* @param {Config} config
* @returns {{ stroke: string, dashInterval: string | null }}
*/

function getLinkShape(linkType, config) {
const linkTypeConfig = config.opts.link_types[linkType];
const stroke = linkTypeConfig?.stroke || 'simple';

switch (stroke) {
case 'simple':
return { stroke: stroke, dashInterval: null };
case 'double':
return { stroke: stroke, dashInterval: null };
case 'dash':
return { stroke: stroke, dashInterval: '4, 5' };
case 'dotted':
return { stroke: stroke, dashInterval: '1, 3' };
}
return { stroke: 'simple', dashInterval: null };
}

/**
*
* @param {Record[]} records
* @param {Config} config
* @returns GraphEngine
*/

export default function getGraph(records, config) {
const graph = new GraphEngine({ multi: true }, config.opts);

/**
* @param {number} degree Node degree
* @returns {number}
*/

records.forEach(({ id, title, types, thumbnail, begin, end }) => {
graph.addNode(id, {
label: title,
types,
thumbnail,
begin,
end,
});
});

records.forEach(({ id: nodeId, wikilinks, bibliographicRecords }) => {
wikilinks.forEach(({ target, type }) => {
graph.addEdge(nodeId, target, {
type,
shape: getLinkShape(type, config),
});
});

bibliographicRecords.forEach(({ target }) => {
if (!graph.hasNode(nodeId) || !graph.hasNode(target)) {
return;
}

return graph.addEdge(nodeId, target, {
type: 'undefined',
shape: getLinkShape('undefined', config),
});
});
});

const degrees = graph.nodes().map((node) => graph.degree(node));
const minDegree = Math.min(...degrees);
const maxDegree = Math.max(...degrees);

graph.updateEachNodeAttributes((node, attr) => {
const size = getNodeSize(graph.degree(node), minDegree, maxDegree, config);
return {
...attr,
size,
};
});

return graph;
}

0 comments on commit cb926a1

Please sign in to comment.