Skip to content

Commit

Permalink
Report weakly connected components
Browse files Browse the repository at this point in the history
  • Loading branch information
thvitt committed Jul 30, 2018
1 parent af9b6d0 commit 556a780
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 16 deletions.
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys

import graph
from report import report_conflicts, report_refs, report_missing
from report import report_components, report_refs, report_missing
from visualize import render_all

logger = logging.getLogger('main')
Expand All @@ -14,7 +14,7 @@ def _main(argv=sys.argv):
graphs = graph.macrogenesis_graphs()
report_refs(graphs)
report_missing(graphs)
report_conflicts(graphs.conflicts)
report_components(graphs)
render_all()


Expand Down
41 changes: 28 additions & 13 deletions report.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,43 @@ def write_html(filename, content, head=None, breadcrumbs=[]):
f.write(suffix)


def report_conflicts(conflicts: List[nx.MultiDiGraph]):
out = target
logger.info('Writing conflict overview to %s', out)
out.mkdir(parents=True, exist_ok=True)
table = HtmlTable().column('Nummer', format_spec='<a href="conflict-{0:02d}.svg">{0}</a>') \
def report_components(graphs: MacrogenesisInfo):
logger.info('Writing component overview to %s', target)
target.mkdir(parents=True, exist_ok=True)
report = f"""<h3>{len(graphs.conflicts)} stark zusammenhängende Komponenten</h3>
<p>Stark zusammenhängende Komponenten sind Teilgraphen, in denen jeder Knoten von
jedem anderen erreichbar ist. Hier ist keine Ordnung möglich, ohne dass Kanten entfernt
werden.</p>
"""
scc_table = _report_subgraphs(graphs.conflicts, target, 'scc-{0:02d}')
report += scc_table.format_table()

wccs = [nx.subgraph(graphs.working, component) for component in nx.weakly_connected_components(graphs.working)]
report += f"""<h3>{len(wccs)} schwach zusammenhängende Komponenten</h3>
<p>Zwischen unterschiedlichen schwach zusammenhängenden Komponenten gibt es keine Verbindungen.</p>"""

wcc_table = _report_subgraphs(wccs, target, 'wcc-{0:02d}')
report += wcc_table.format_table()
write_html(target / 'components.php', report, head="Komponenten")


def _report_subgraphs(subgraphs, out, pattern):
table = HtmlTable().column('Nummer', format_spec='<a href="'+pattern+'.svg">{0}</a>') \
.column('Dokumente') \
.column('Relationen') \
.column('Entfernte Relationen') \
.column('Quellen', format_spec=lambda s: ", ".join(map(str, s))) \
.column('Entfernte Quellen', format_spec=lambda s: ", ".join(map(str, s)))

for index, subgraph in enumerate(conflicts, start=1):
for index, subgraph in enumerate(subgraphs, start=1):
refs = len([node for node in subgraph.nodes if isinstance(node, Reference)])
all_edges = list(subgraph.edges(keys=True, data=True))
conflicts = [(u, v, k, attr) for (u, v, k, attr) in all_edges if 'delete' in attr and attr['delete']]
subgraphs = [(u, v, k, attr) for (u, v, k, attr) in all_edges if 'delete' in attr and attr['delete']]
relations = [(u, v, k, attr) for (u, v, k, attr) in all_edges if 'delete' not in attr or not attr['delete']]
sources = {attr['source'].citation for u, v, k, attr in relations if 'source' in attr}
conflict_sources = {attr['source'].citation for u, v, k, attr in conflicts}
table.row((index, refs, len(relations), len(conflicts), sources, conflict_sources))
write_dot(subgraph, out / "conflict-{:02d}.dot".format(index))

write_html(out / 'conflicts.php', table.format_table(), breadcrumbs=[dict(caption="Makrogenese", link='/macrogenesis'), dict(caption="Komponenten")])
conflict_sources = {attr['source'].citation for u, v, k, attr in subgraphs}
table.row((index, refs, len(relations), len(subgraphs), sources, conflict_sources))
write_dot(subgraph, out / (pattern+".dot").format(index))
return table


def write_bibliography_stats(graph: nx.MultiDiGraph):
Expand Down
6 changes: 5 additions & 1 deletion visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ def _load_style(filename):
return yaml.load(f)


def write_dot(graph: nx.MultiDiGraph, target='base_graph.dot', style=_load_style('styles.yaml'), highlight=None, record=True):
def write_dot(graph: nx.MultiDiGraph, target='base_graph.dot', style=_load_style('styles.yaml'), highlight=None, record='auto'):
logger.info('Writing %s ...', target)
if record == 'auto':
record = len(graph.edges) < 1000

vis = graph.copy()
add_timeline_edges(vis)
Expand Down Expand Up @@ -120,6 +122,8 @@ def write_dot(graph: nx.MultiDiGraph, target='base_graph.dot', style=_load_style
agraph.write(dotfilename)
if record:
_render_queue.append(dotfilename)
else:
logger.warning('%s has not been queued for rendering', dotfilename)


def render_file(filename):
Expand Down

0 comments on commit 556a780

Please sign in to comment.