6 |
7 | Source Viz is a tool for analyzing and visualizing the relationship
8 | between the public API of a Module\Class and its implementation details
9 | (e.g. private methods, dependencies used).
10 |
11 |
12 | Ideally this visualization can help you spot logical split-points in a
13 | huge Module\Class file by highlighting how one set of public methods
14 | uses completely different code than a different set.
15 |
16 |
17 | To use it just paste your code below and click Analyze.
18 |
19 |
20 | Results are displayed in an{' '}
21 |
25 | Adjacency Matrix
26 |
27 | .
28 |
29 |
30 | Right now it supports analyzing{' '}
31 |
32 | Typescript
33 | {' '}
34 | (and therefore Javascript as well).
35 |
36 | Support for other programming languages is also planned.
37 |
38 |
39 | Feel free to open up an issue on{' '}
40 |
41 | github
42 | {' '}
43 | or reach out on{' '}
44 |
45 | twitter
46 |
47 | .
48 |
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/packages/source-viz-vscode/README.md:
--------------------------------------------------------------------------------
1 | **Source Viz** is a VSCode extension for visualizing the relationship between a module's public API and its implementation details.
2 |
3 | You can use it to
4 | * Make changes with confidence
5 | * Quickly get a sense of what a module does (i.e. what are its exported functions) and how (i.e. using which helper functions \ imports).
6 | * Find refactoring opportunities
7 | * Identify how to split-up a large file (e.g. if a single public method uses a completely different code path than the rest of the public methods).
8 |
9 | ## Functionality
10 |
11 | Press Cmd\Ctrl+Shift+P and select "**Open Source Viz**" to see the diagram of the file you are currently editing.
12 |
13 | 
14 |
15 | ## Interpreting the results
16 |
17 | The results are displayed in an [Adjacency Matrix](https://en.wikipedia.org/wiki/Adjacency_matrix).
18 |
19 | 
20 |
21 | * The **rows** represent the module's public API.
22 | These would be its exported functions.
23 | * The **columns** represent the module's internal implementation
24 | These would be:
25 | * 🔐 Non-exported (private) functions
26 | * 📦 Imported members (dependencies)
27 |
28 | Notice that in order to provide an accurate representation of the structure of real-world complex code, Source Viz follows functions as transitive links. For example, even though `depA` is not used directly in the source of `methodA`, it is marked as used by it because `methodA` uses `methodC` and `methodC` does use `depA`.
29 | You can turn off this default behavior by unchecking "Private Method" as "Transitive links" in the controls.
30 |
31 | 
32 |
--------------------------------------------------------------------------------
/packages/source-viz-core/src/core/view-model/sort.ts:
--------------------------------------------------------------------------------
1 | import { jLouvain } from 'louvain';
2 | import * as shuffle from 'lodash.shuffle';
3 | import { SortType } from './view-config';
4 | import { MatrixModel } from './matrix-model';
5 | import { getSortByEmptyRowsLastFunc } from './getSortByEmptyRowsLastFunc';
6 |
7 | const sortFuncs = {
8 | [SortType.alphabetical]: sortByAlphabetical,
9 | [SortType.random]: sortByRandom,
10 | [SortType.louvain]: sortByLouvain,
11 | };
12 |
13 | export function sort(model: MatrixModel, sortType: SortType) {
14 | return sortFuncs[sortType](model);
15 | }
16 |
17 | function sortByAlphabetical(model: MatrixModel) {
18 | model.rows.sort((a, b) => a.localeCompare(b));
19 | model.columns.sort((a, b) => a.label.localeCompare(b.label));
20 | }
21 |
22 | function sortByRandom(model: MatrixModel) {
23 | model.rows = shuffle(model.rows);
24 | model.columns = shuffle(model.columns);
25 | }
26 |
27 | function sortByLouvain(model: MatrixModel) {
28 | if (model.links.length === 0) {
29 | return;
30 | }
31 | const nodes = model.rows.concat(model.columns.map((x) => x.label));
32 | const edges = model.links.map((x) => ({
33 | source: x.row,
34 | target: x.column.label,
35 | value: 1,
36 | }));
37 | const community = jLouvain().nodes(nodes).edges(edges);
38 | const sorted = community();
39 |
40 | const sortyByEmptyRowsLastFunc = getSortByEmptyRowsLastFunc(
41 | model.rows,
42 | model.links,
43 | );
44 |
45 | model.rows.sort((a, b) => {
46 | const sortByEmptyRowsLastResult = sortyByEmptyRowsLastFunc(a, b);
47 | if (sortByEmptyRowsLastResult != 0) {
48 | return sortByEmptyRowsLastResult;
49 | }
50 | return sorted[a] - sorted[b];
51 | });
52 | model.columns.sort((a, b) => sorted[a.label] - sorted[b.label]);
53 | }
54 |
--------------------------------------------------------------------------------
/packages/source-viz-web/src/components/App.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { SourcePanel } from './SourcePanel';
3 | import { AnalysisMode, SourceMatrix } from 'source-viz-core';
4 | import { examples } from '../examples';
5 | import { Description } from './Description';
6 | import { Title } from './Title';
7 | import { Mode } from './Mode';
8 |
9 | interface AppState {
10 | mode: AnalysisMode;
11 | initialCode: string;
12 | draftCode: string;
13 | code: string;
14 | }
15 |
16 | export class App extends React.Component