@graphty/graph-io 0.3.43 → 0.3.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
- package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
- package/dist/chunks/block-JQiwViEt.js +2777 -0
- package/dist/chunks/block-JQiwViEt.js.map +1 -0
- package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
- package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
- package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
- package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
- package/dist/chunks/convert-BcQ8_jMo.js +59 -0
- package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
- package/dist/chunks/emit-DCwFLts5.js +3456 -0
- package/dist/chunks/emit-DCwFLts5.js.map +1 -0
- package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
- package/dist/chunks/escape-B1rMftd9.js.map +1 -0
- package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
- package/dist/chunks/export-D7IGzTG4.js.map +1 -0
- package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
- package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
- package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
- package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
- package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
- package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
- package/dist/chunks/{exporter-RVtXVetw.js → exporter-quPUCBiC.js} +1805 -287
- package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
- package/dist/chunks/format-GDmO6m6Q.js +676 -0
- package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
- package/dist/chunks/generic-BL06jrJf.js +1347 -0
- package/dist/chunks/generic-BL06jrJf.js.map +1 -0
- package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
- package/dist/chunks/importer-B7r2owVf.js.map +1 -0
- package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
- package/dist/chunks/importer-BFmOP96W.js.map +1 -0
- package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
- package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
- package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
- package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
- package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
- package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
- package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
- package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
- package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
- package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
- package/dist/chunks/index-B9fdNpTA.js +4310 -0
- package/dist/chunks/index-B9fdNpTA.js.map +1 -0
- package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
- package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
- package/dist/chunks/lexicon-B-knUi-l.js +508 -0
- package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
- package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
- package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
- package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
- package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
- package/dist/chunks/styles-Brt9JMfs.js +690 -0
- package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
- package/dist/chunks/styles-_N-C8S-U.js +2102 -0
- package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
- package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
- package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
- package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
- package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
- package/dist/chunks/units-XMZFIFe1.js +19 -0
- package/dist/chunks/units-XMZFIFe1.js.map +1 -0
- package/dist/csv.js +5 -4
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +5 -2
- package/dist/dot.js.map +1 -1
- package/dist/gexf.js +292 -412
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +8 -3031
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +354 -240
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +4 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +4 -3
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +4 -2
- package/dist/positions.d.ts +1 -0
- package/dist/positions.js +427 -0
- package/dist/positions.js.map +1 -0
- package/dist/src/common/codes.d.ts +6 -0
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +6 -0
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +4 -2
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +10 -0
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +123 -100
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +8 -1
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +12 -9
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +160 -37
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/notes.d.ts +42 -0
- package/dist/src/common/notes.d.ts.map +1 -0
- package/dist/src/common/notes.js +72 -0
- package/dist/src/common/notes.js.map +1 -0
- package/dist/src/common/report.d.ts +18 -0
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +36 -1
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/units.d.ts +24 -0
- package/dist/src/common/units.d.ts.map +1 -0
- package/dist/src/common/units.js +26 -0
- package/dist/src/common/units.js.map +1 -0
- package/dist/src/common/xml.d.ts +18 -0
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +42 -5
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +6 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx/exporter.js +71 -8
- package/dist/src/formats/cx/exporter.js.map +1 -1
- package/dist/src/formats/cx/importer.d.ts +5 -2
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +102 -72
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts +102 -0
- package/dist/src/formats/cx/styles.d.ts.map +1 -0
- package/dist/src/formats/cx/styles.js +225 -0
- package/dist/src/formats/cx/styles.js.map +1 -0
- package/dist/src/formats/cx2/exporter.d.ts +5 -0
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +181 -71
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +4 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +19 -1
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/styles.d.ts +18 -0
- package/dist/src/formats/cx2/styles.d.ts.map +1 -0
- package/dist/src/formats/cx2/styles.js +24 -0
- package/dist/src/formats/cx2/styles.js.map +1 -0
- package/dist/src/formats/cys/constants.d.ts +2 -0
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +2 -0
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +6 -2
- package/dist/src/formats/cys/exporter.d.ts.map +1 -1
- package/dist/src/formats/cys/exporter.js +215 -53
- package/dist/src/formats/cys/exporter.js.map +1 -1
- package/dist/src/formats/cys/importer.d.ts +2 -1
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +119 -6
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +2 -0
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +5 -0
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/styles.d.ts +38 -0
- package/dist/src/formats/cys/styles.d.ts.map +1 -0
- package/dist/src/formats/cys/styles.js +213 -0
- package/dist/src/formats/cys/styles.js.map +1 -0
- package/dist/src/formats/cys/tables.d.ts +8 -3
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +88 -34
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +2 -0
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +195 -81
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +100 -20
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +1 -0
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +1 -0
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/positions.d.ts +14 -0
- package/dist/src/formats/dot/positions.d.ts.map +1 -0
- package/dist/src/formats/dot/positions.js +70 -0
- package/dist/src/formats/dot/positions.js.map +1 -0
- package/dist/src/formats/dot/styles.d.ts +82 -0
- package/dist/src/formats/dot/styles.d.ts.map +1 -0
- package/dist/src/formats/dot/styles.js +1484 -0
- package/dist/src/formats/dot/styles.js.map +1 -0
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +20 -5
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +8 -1
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +251 -131
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +8 -0
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +10 -2
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +5 -0
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +5 -0
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +74 -0
- package/dist/src/formats/gexf/styles.d.ts.map +1 -0
- package/dist/src/formats/gexf/styles.js +604 -0
- package/dist/src/formats/gexf/styles.js.map +1 -0
- package/dist/src/formats/gml/exporter.d.ts +1 -5
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +19 -8
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +4 -0
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +2 -1
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +2 -1
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/positions.d.ts +14 -0
- package/dist/src/formats/gml/positions.d.ts.map +1 -0
- package/dist/src/formats/gml/positions.js +46 -0
- package/dist/src/formats/gml/positions.js.map +1 -0
- package/dist/src/formats/gml/styles.d.ts +59 -0
- package/dist/src/formats/gml/styles.d.ts.map +1 -0
- package/dist/src/formats/gml/styles.js +1056 -0
- package/dist/src/formats/gml/styles.js.map +1 -0
- package/dist/src/formats/gml/syntax.d.ts +11 -0
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +151 -62
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +4 -0
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +5 -1
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +133 -65
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +4 -1
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +100 -44
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +1 -0
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +1 -0
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-plain.js +187 -0
- package/dist/src/formats/graphml/styles-plain.js.map +1 -0
- package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yed.js +1086 -0
- package/dist/src/formats/graphml/styles-yed.js.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +34 -19
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +16 -2
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +83 -12
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +5 -0
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +68 -25
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +22 -3
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +439 -264
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/positions.d.ts +16 -0
- package/dist/src/formats/json/positions.d.ts.map +1 -0
- package/dist/src/formats/json/positions.js +44 -0
- package/dist/src/formats/json/positions.js.map +1 -0
- package/dist/src/formats/json/styles.d.ts +102 -0
- package/dist/src/formats/json/styles.d.ts.map +1 -0
- package/dist/src/formats/json/styles.js +1753 -0
- package/dist/src/formats/json/styles.js.map +1 -0
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +2 -1
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +2 -0
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +142 -76
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +4 -0
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +60 -6
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -0
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -0
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts +50 -0
- package/dist/src/formats/pajek/styles.d.ts.map +1 -0
- package/dist/src/formats/pajek/styles.js +569 -0
- package/dist/src/formats/pajek/styles.js.map +1 -0
- package/dist/src/formats/pajek/syntax.d.ts +6 -0
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +6 -0
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +34 -9
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +2 -0
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +3 -1
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +12 -8
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +56 -13
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +12 -6
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +3 -1
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +22 -9
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +2 -1
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +31 -24
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts +104 -0
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
- package/dist/src/formats/xgmml/styles.js +310 -0
- package/dist/src/formats/xgmml/styles.js.map +1 -0
- package/dist/src/index.d.ts +9 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -7
- package/dist/src/index.js.map +1 -1
- package/dist/src/positions/codes.d.ts +31 -0
- package/dist/src/positions/codes.d.ts.map +1 -0
- package/dist/src/positions/codes.js +26 -0
- package/dist/src/positions/codes.js.map +1 -0
- package/dist/src/positions/convert.d.ts +58 -0
- package/dist/src/positions/convert.d.ts.map +1 -0
- package/dist/src/positions/convert.js +107 -0
- package/dist/src/positions/convert.js.map +1 -0
- package/dist/src/positions/extract.d.ts +27 -0
- package/dist/src/positions/extract.d.ts.map +1 -0
- package/dist/src/positions/extract.js +526 -0
- package/dist/src/positions/extract.js.map +1 -0
- package/dist/src/positions/index.d.ts +10 -0
- package/dist/src/positions/index.d.ts.map +1 -0
- package/dist/src/positions/index.js +9 -0
- package/dist/src/positions/index.js.map +1 -0
- package/dist/src/positions/types.d.ts +208 -0
- package/dist/src/positions/types.d.ts.map +1 -0
- package/dist/src/positions/types.js +10 -0
- package/dist/src/positions/types.js.map +1 -0
- package/dist/src/registry.d.ts +30 -0
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +130 -9
- package/dist/src/registry.js.map +1 -1
- package/dist/src/styles/annotations.d.ts +132 -0
- package/dist/src/styles/annotations.d.ts.map +1 -0
- package/dist/src/styles/annotations.js +320 -0
- package/dist/src/styles/annotations.js.map +1 -0
- package/dist/src/styles/budget.d.ts +45 -0
- package/dist/src/styles/budget.d.ts.map +1 -0
- package/dist/src/styles/budget.js +58 -0
- package/dist/src/styles/budget.js.map +1 -0
- package/dist/src/styles/canon/bends.d.ts +32 -0
- package/dist/src/styles/canon/bends.d.ts.map +1 -0
- package/dist/src/styles/canon/bends.js +74 -0
- package/dist/src/styles/canon/bends.js.map +1 -0
- package/dist/src/styles/canon/color-tables.d.ts +22 -0
- package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
- package/dist/src/styles/canon/color-tables.js +369 -0
- package/dist/src/styles/canon/color-tables.js.map +1 -0
- package/dist/src/styles/canon/color.d.ts +66 -0
- package/dist/src/styles/canon/color.d.ts.map +1 -0
- package/dist/src/styles/canon/color.js +548 -0
- package/dist/src/styles/canon/color.js.map +1 -0
- package/dist/src/styles/canon/enums.d.ts +25 -0
- package/dist/src/styles/canon/enums.d.ts.map +1 -0
- package/dist/src/styles/canon/enums.js +187 -0
- package/dist/src/styles/canon/enums.js.map +1 -0
- package/dist/src/styles/canon/graphviz.d.ts +48 -0
- package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
- package/dist/src/styles/canon/graphviz.js +160 -0
- package/dist/src/styles/canon/graphviz.js.map +1 -0
- package/dist/src/styles/canon/index.d.ts +13 -0
- package/dist/src/styles/canon/index.d.ts.map +1 -0
- package/dist/src/styles/canon/index.js +13 -0
- package/dist/src/styles/canon/index.js.map +1 -0
- package/dist/src/styles/canon/number.d.ts +59 -0
- package/dist/src/styles/canon/number.d.ts.map +1 -0
- package/dist/src/styles/canon/number.js +142 -0
- package/dist/src/styles/canon/number.js.map +1 -0
- package/dist/src/styles/canon/site.d.ts +51 -0
- package/dist/src/styles/canon/site.d.ts.map +1 -0
- package/dist/src/styles/canon/site.js +63 -0
- package/dist/src/styles/canon/site.js.map +1 -0
- package/dist/src/styles/canon/text.d.ts +61 -0
- package/dist/src/styles/canon/text.d.ts.map +1 -0
- package/dist/src/styles/canon/text.js +199 -0
- package/dist/src/styles/canon/text.js.map +1 -0
- package/dist/src/styles/codes.d.ts +95 -0
- package/dist/src/styles/codes.d.ts.map +1 -0
- package/dist/src/styles/codes.js +97 -0
- package/dist/src/styles/codes.js.map +1 -0
- package/dist/src/styles/cyjs/cascade.d.ts +134 -0
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
- package/dist/src/styles/cyjs/cascade.js +2252 -0
- package/dist/src/styles/cyjs/cascade.js.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.js +76 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
- package/dist/src/styles/cyjs/emit.d.ts +82 -0
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
- package/dist/src/styles/cyjs/emit.js +790 -0
- package/dist/src/styles/cyjs/emit.js.map +1 -0
- package/dist/src/styles/cyjs/index.d.ts +13 -0
- package/dist/src/styles/cyjs/index.d.ts.map +1 -0
- package/dist/src/styles/cyjs/index.js +13 -0
- package/dist/src/styles/cyjs/index.js.map +1 -0
- package/dist/src/styles/cyjs/live.d.ts +46 -0
- package/dist/src/styles/cyjs/live.d.ts.map +1 -0
- package/dist/src/styles/cyjs/live.js +108 -0
- package/dist/src/styles/cyjs/live.js.map +1 -0
- package/dist/src/styles/cyjs/mappers.d.ts +147 -0
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
- package/dist/src/styles/cyjs/mappers.js +744 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -0
- package/dist/src/styles/cyjs/selector.d.ts +113 -0
- package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
- package/dist/src/styles/cyjs/selector.js +611 -0
- package/dist/src/styles/cyjs/selector.js.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
- package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
- package/dist/src/styles/cytoscape/emit.d.ts +125 -0
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/emit.js +1025 -0
- package/dist/src/styles/cytoscape/emit.js.map +1 -0
- package/dist/src/styles/cytoscape/index.d.ts +10 -0
- package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/index.js +10 -0
- package/dist/src/styles/cytoscape/index.js.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.js +603 -0
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
- package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
- package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/mappings.js +460 -0
- package/dist/src/styles/cytoscape/mappings.js.map +1 -0
- package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/resolve.js +381 -0
- package/dist/src/styles/cytoscape/resolve.js.map +1 -0
- package/dist/src/styles/cytoscape/translate.d.ts +50 -0
- package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/translate.js +156 -0
- package/dist/src/styles/cytoscape/translate.js.map +1 -0
- package/dist/src/styles/defaults.d.ts +90 -0
- package/dist/src/styles/defaults.d.ts.map +1 -0
- package/dist/src/styles/defaults.js +414 -0
- package/dist/src/styles/defaults.js.map +1 -0
- package/dist/src/styles/index.d.ts +15 -0
- package/dist/src/styles/index.d.ts.map +1 -0
- package/dist/src/styles/index.js +14 -0
- package/dist/src/styles/index.js.map +1 -0
- package/dist/src/styles/internal.d.ts +17 -0
- package/dist/src/styles/internal.d.ts.map +1 -0
- package/dist/src/styles/internal.js +16 -0
- package/dist/src/styles/internal.js.map +1 -0
- package/dist/src/styles/io/approximations.d.ts +24 -0
- package/dist/src/styles/io/approximations.d.ts.map +1 -0
- package/dist/src/styles/io/approximations.js +51 -0
- package/dist/src/styles/io/approximations.js.map +1 -0
- package/dist/src/styles/io/block.d.ts +166 -0
- package/dist/src/styles/io/block.d.ts.map +1 -0
- package/dist/src/styles/io/block.js +930 -0
- package/dist/src/styles/io/block.js.map +1 -0
- package/dist/src/styles/io/generic.d.ts +88 -0
- package/dist/src/styles/io/generic.d.ts.map +1 -0
- package/dist/src/styles/io/generic.js +516 -0
- package/dist/src/styles/io/generic.js.map +1 -0
- package/dist/src/styles/io/index.d.ts +8 -0
- package/dist/src/styles/io/index.d.ts.map +1 -0
- package/dist/src/styles/io/index.js +7 -0
- package/dist/src/styles/io/index.js.map +1 -0
- package/dist/src/styles/io/writer.d.ts +80 -0
- package/dist/src/styles/io/writer.d.ts.map +1 -0
- package/dist/src/styles/io/writer.js +596 -0
- package/dist/src/styles/io/writer.js.map +1 -0
- package/dist/src/styles/notes.d.ts +47 -0
- package/dist/src/styles/notes.d.ts.map +1 -0
- package/dist/src/styles/notes.js +140 -0
- package/dist/src/styles/notes.js.map +1 -0
- package/dist/src/styles/plan/classes.d.ts +31 -0
- package/dist/src/styles/plan/classes.d.ts.map +1 -0
- package/dist/src/styles/plan/classes.js +139 -0
- package/dist/src/styles/plan/classes.js.map +1 -0
- package/dist/src/styles/plan/continuous.d.ts +32 -0
- package/dist/src/styles/plan/continuous.d.ts.map +1 -0
- package/dist/src/styles/plan/continuous.js +165 -0
- package/dist/src/styles/plan/continuous.js.map +1 -0
- package/dist/src/styles/plan/discrete.d.ts +39 -0
- package/dist/src/styles/plan/discrete.d.ts.map +1 -0
- package/dist/src/styles/plan/discrete.js +127 -0
- package/dist/src/styles/plan/discrete.js.map +1 -0
- package/dist/src/styles/plan/families.d.ts +31 -0
- package/dist/src/styles/plan/families.d.ts.map +1 -0
- package/dist/src/styles/plan/families.js +95 -0
- package/dist/src/styles/plan/families.js.map +1 -0
- package/dist/src/styles/plan/features.d.ts +58 -0
- package/dist/src/styles/plan/features.d.ts.map +1 -0
- package/dist/src/styles/plan/features.js +185 -0
- package/dist/src/styles/plan/features.js.map +1 -0
- package/dist/src/styles/plan/index.d.ts +7 -0
- package/dist/src/styles/plan/index.d.ts.map +1 -0
- package/dist/src/styles/plan/index.js +7 -0
- package/dist/src/styles/plan/index.js.map +1 -0
- package/dist/src/styles/plan/plan.d.ts +71 -0
- package/dist/src/styles/plan/plan.d.ts.map +1 -0
- package/dist/src/styles/plan/plan.js +893 -0
- package/dist/src/styles/plan/plan.js.map +1 -0
- package/dist/src/styles/plan/resolve.d.ts +137 -0
- package/dist/src/styles/plan/resolve.d.ts.map +1 -0
- package/dist/src/styles/plan/resolve.js +587 -0
- package/dist/src/styles/plan/resolve.js.map +1 -0
- package/dist/src/styles/types.d.ts +702 -0
- package/dist/src/styles/types.d.ts.map +1 -0
- package/dist/src/styles/types.js +10 -0
- package/dist/src/styles/types.js.map +1 -0
- package/dist/src/styles/vocabulary.d.ts +41 -0
- package/dist/src/styles/vocabulary.d.ts.map +1 -0
- package/dist/src/styles/vocabulary.js +140 -0
- package/dist/src/styles/vocabulary.js.map +1 -0
- package/dist/src/types.d.ts +64 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/styles.d.ts +1 -0
- package/dist/styles.js +322 -0
- package/dist/styles.js.map +1 -0
- package/dist/xgmml.js +5 -4
- package/dist/xgmml.js.map +1 -1
- package/package.json +13 -2
- package/src/common/codes.ts +7 -0
- package/src/common/escape.ts +5 -2
- package/src/common/export.ts +179 -140
- package/src/common/input.ts +8 -4
- package/src/common/json-elements.ts +169 -38
- package/src/common/notes.ts +94 -0
- package/src/common/report.ts +41 -1
- package/src/common/units.ts +42 -0
- package/src/common/xml.ts +45 -5
- package/src/formats/cx/exporter.ts +95 -11
- package/src/formats/cx/importer.ts +126 -90
- package/src/formats/cx/styles.ts +304 -0
- package/src/formats/cx2/exporter.ts +234 -77
- package/src/formats/cx2/importer.ts +19 -1
- package/src/formats/cx2/styles.ts +29 -0
- package/src/formats/cys/constants.ts +3 -0
- package/src/formats/cys/exporter.ts +246 -60
- package/src/formats/cys/importer.ts +125 -9
- package/src/formats/cys/session.ts +6 -0
- package/src/formats/cys/styles.ts +254 -0
- package/src/formats/cys/tables.ts +117 -48
- package/src/formats/dot/exporter.ts +262 -126
- package/src/formats/dot/importer.ts +111 -20
- package/src/formats/dot/index.ts +1 -0
- package/src/formats/dot/positions.ts +77 -0
- package/src/formats/dot/styles.ts +1741 -0
- package/src/formats/gexf/exporter.ts +27 -11
- package/src/formats/gexf/importer.ts +308 -158
- package/src/formats/gexf/index.ts +10 -0
- package/src/formats/gexf/schema.ts +5 -0
- package/src/formats/gexf/styles.ts +719 -0
- package/src/formats/gml/exporter.ts +33 -14
- package/src/formats/gml/importer.ts +4 -0
- package/src/formats/gml/index.ts +2 -1
- package/src/formats/gml/positions.ts +52 -0
- package/src/formats/gml/styles.ts +1248 -0
- package/src/formats/gml/syntax.ts +173 -62
- package/src/formats/graphml/constants.ts +5 -0
- package/src/formats/graphml/exporter.ts +163 -71
- package/src/formats/graphml/importer.ts +119 -45
- package/src/formats/graphml/index.ts +1 -0
- package/src/formats/graphml/styles-plain.ts +236 -0
- package/src/formats/graphml/styles-yed.ts +1221 -0
- package/src/formats/graphml/styles-yfiles3.ts +573 -0
- package/src/formats/graphml/tree.ts +36 -20
- package/src/formats/graphml/yfiles.ts +89 -13
- package/src/formats/json/exporter.ts +76 -26
- package/src/formats/json/importer.ts +541 -322
- package/src/formats/json/positions.ts +50 -0
- package/src/formats/json/styles.ts +2082 -0
- package/src/formats/neo4j/exporter.ts +2 -1
- package/src/formats/pajek/exporter.ts +195 -106
- package/src/formats/pajek/importer.ts +78 -9
- package/src/formats/pajek/index.ts +2 -0
- package/src/formats/pajek/styles.ts +685 -0
- package/src/formats/pajek/syntax.ts +7 -0
- package/src/formats/xgmml/columns.ts +39 -9
- package/src/formats/xgmml/constants.ts +3 -0
- package/src/formats/xgmml/document.ts +54 -12
- package/src/formats/xgmml/emit.ts +11 -6
- package/src/formats/xgmml/exporter.ts +32 -13
- package/src/formats/xgmml/importer.ts +43 -29
- package/src/formats/xgmml/styles.ts +400 -0
- package/src/index.ts +16 -0
- package/src/positions/codes.ts +32 -0
- package/src/positions/convert.ts +123 -0
- package/src/positions/extract.ts +619 -0
- package/src/positions/index.ts +23 -0
- package/src/positions/types.ts +221 -0
- package/src/registry.ts +179 -8
- package/src/styles/annotations.ts +478 -0
- package/src/styles/budget.ts +60 -0
- package/src/styles/canon/bends.ts +84 -0
- package/src/styles/canon/color-tables.ts +386 -0
- package/src/styles/canon/color.ts +624 -0
- package/src/styles/canon/enums.ts +211 -0
- package/src/styles/canon/graphviz.ts +189 -0
- package/src/styles/canon/index.ts +13 -0
- package/src/styles/canon/number.ts +152 -0
- package/src/styles/canon/site.ts +87 -0
- package/src/styles/canon/text.ts +221 -0
- package/src/styles/codes.ts +104 -0
- package/src/styles/cyjs/cascade.ts +2670 -0
- package/src/styles/cyjs/defaults-table.ts +82 -0
- package/src/styles/cyjs/emit.ts +951 -0
- package/src/styles/cyjs/index.ts +37 -0
- package/src/styles/cyjs/live.ts +147 -0
- package/src/styles/cyjs/mappers.ts +879 -0
- package/src/styles/cyjs/selector.ts +778 -0
- package/src/styles/cyjs/stylesheet-text.ts +214 -0
- package/src/styles/cytoscape/emit.ts +1264 -0
- package/src/styles/cytoscape/index.ts +40 -0
- package/src/styles/cytoscape/lexicon.ts +656 -0
- package/src/styles/cytoscape/mappings.ts +603 -0
- package/src/styles/cytoscape/resolve.ts +521 -0
- package/src/styles/cytoscape/translate.ts +237 -0
- package/src/styles/defaults.ts +504 -0
- package/src/styles/index.ts +57 -0
- package/src/styles/internal.ts +17 -0
- package/src/styles/io/approximations.ts +47 -0
- package/src/styles/io/block.ts +1138 -0
- package/src/styles/io/generic.ts +687 -0
- package/src/styles/io/index.ts +18 -0
- package/src/styles/io/writer.ts +745 -0
- package/src/styles/notes.ts +165 -0
- package/src/styles/plan/classes.ts +166 -0
- package/src/styles/plan/continuous.ts +218 -0
- package/src/styles/plan/discrete.ts +165 -0
- package/src/styles/plan/families.ts +115 -0
- package/src/styles/plan/features.ts +234 -0
- package/src/styles/plan/index.ts +7 -0
- package/src/styles/plan/plan.ts +1129 -0
- package/src/styles/plan/resolve.ts +685 -0
- package/src/styles/types.ts +814 -0
- package/src/styles/vocabulary.ts +172 -0
- package/src/types.ts +76 -1
- package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
- package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
- package/dist/chunks/export-rKLeGQMo.js.map +0 -1
- package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
- package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
- package/dist/chunks/exporter-RVtXVetw.js.map +0 -1
- package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
- package/dist/chunks/importer-C98dpSH4.js.map +0 -1
- package/dist/chunks/importer-D794XUTe.js.map +0 -1
- package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
- package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
- package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
- package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
- package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
|
@@ -0,0 +1,1056 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GML styles: each node's and edge's `graphics [ ... ]` and `LabelGraphics [ ... ]` records read the way the program
|
|
3
|
+
* that wrote the file draws them, and a graph's styles written back as yEd GML graphics.
|
|
4
|
+
*
|
|
5
|
+
* GML has one syntax and many vocabularies. The `Creator` line (top level, or inside the graph as Gephi writes it,
|
|
6
|
+
* quoted or not) names the writer: yEd and yFiles, Cytoscape, Gephi, OGDF and igraph are recognized; every other file
|
|
7
|
+
* (NetworkX writes no `Creator`) is read with the keys of the GML draft (Graphlet). A recognized drawing program's
|
|
8
|
+
* defaults go beneath the file's own values; igraph and unknown writers get none.
|
|
9
|
+
*
|
|
10
|
+
* Writing: the yEd keys (`fill`, `outline`, `outlineWidth`, `outlineStyle`, `w`, `h`, `type`; edge `fill`, `width`,
|
|
11
|
+
* `style`, `sourceArrow`, `targetArrow`, `smoothBends`; `LabelGraphics` `text`, `color`, `fontSize`, `fontName`,
|
|
12
|
+
* `fontStyle`) replace every style key any reader here reads, inside the records the graph already has, so positions,
|
|
13
|
+
* bends and other keys stay. The `graphty.styles` block and the per-element values its rules read are keys too,
|
|
14
|
+
* named by the GML writer's rule for names that are not GML keys (`graphty_styles`, `graphty_style_node_<key>`).
|
|
15
|
+
*/
|
|
16
|
+
import { bendsToPoints, canonBends } from "../../styles/canon/bends.js";
|
|
17
|
+
import { canonColor, colorOpacity } from "../../styles/canon/color.js";
|
|
18
|
+
import { canonEnum } from "../../styles/canon/enums.js";
|
|
19
|
+
import { canonNumber } from "../../styles/canon/number.js";
|
|
20
|
+
import { MAX_STYLE_VALUE_LENGTH, noteAt, scalarText } from "../../styles/canon/site.js";
|
|
21
|
+
import { canonText } from "../../styles/canon/text.js";
|
|
22
|
+
import { STYLE_ISSUE } from "../../styles/codes.js";
|
|
23
|
+
import { CYTOSCAPE_LEXICON } from "../../styles/cytoscape/lexicon.js";
|
|
24
|
+
import { StyleApproximations } from "../../styles/io/approximations.js";
|
|
25
|
+
import { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME, styleBlockLosses, styleTag, writeStyleBlock, } from "../../styles/io/block.js";
|
|
26
|
+
import { dataRead } from "../../styles/io/writer.js";
|
|
27
|
+
import { StyleNotes } from "../../styles/notes.js";
|
|
28
|
+
import { styleFingerprint } from "../../styles/plan/features.js";
|
|
29
|
+
import { plainCell, resolveStyles } from "../../styles/plan/resolve.js";
|
|
30
|
+
import { gephiRules } from "../gexf/styles.js";
|
|
31
|
+
import { flowchartShape, FONT_STYLES, valueColumns, YED_ARROWS, YED_LINES, YED_SHAPES, yedColor, yedSpelled, yedValue, } from "../graphml/styles-yed.js";
|
|
32
|
+
import { KEY_MANGLED_CODE, mangleGmlKey } from "./syntax.js";
|
|
33
|
+
/** The writers recognized by their `Creator` text, first match wins. */
|
|
34
|
+
const WRITERS = [
|
|
35
|
+
[
|
|
36
|
+
/^\s*(yfiles|yed)\b/i,
|
|
37
|
+
{ dialect: "yed", tool: "yed", vocabulary: "yed", spelling: "yed", units: "px", labelKey: false },
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
/^\s*cytoscape\b/i,
|
|
41
|
+
{
|
|
42
|
+
dialect: "cytoscape",
|
|
43
|
+
tool: "cytoscape",
|
|
44
|
+
vocabulary: "cytoscape",
|
|
45
|
+
spelling: "cytoscape",
|
|
46
|
+
units: "px",
|
|
47
|
+
labelKey: true,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
/^\s*gephi\b/i,
|
|
52
|
+
{
|
|
53
|
+
dialect: "gephi",
|
|
54
|
+
tool: "gephi",
|
|
55
|
+
vocabulary: "graphlet",
|
|
56
|
+
spelling: "css",
|
|
57
|
+
units: "relative",
|
|
58
|
+
labelKey: false,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
/^\s*ogdf::/i,
|
|
63
|
+
{ dialect: "ogdf", tool: "ogdf", vocabulary: "ogdf", spelling: "css", units: "px", labelKey: true },
|
|
64
|
+
],
|
|
65
|
+
// igraph writes a Creator line, but no drawing defaults of igraph's are stated by a primary source
|
|
66
|
+
[
|
|
67
|
+
/^\s*igraph\b/i,
|
|
68
|
+
{ dialect: "igraph", tool: null, vocabulary: "graphlet", spelling: "css", units: "px", labelKey: true },
|
|
69
|
+
],
|
|
70
|
+
];
|
|
71
|
+
/** Any other writer (NetworkX, SNDlib, hand-written files): the GML draft's keys, no defaults. */
|
|
72
|
+
const UNKNOWN_WRITER = {
|
|
73
|
+
dialect: "gml",
|
|
74
|
+
tool: null,
|
|
75
|
+
vocabulary: "graphlet",
|
|
76
|
+
spelling: "css",
|
|
77
|
+
units: "px",
|
|
78
|
+
labelKey: true,
|
|
79
|
+
};
|
|
80
|
+
/** A file graphty wrote: yEd keys, and the `graphty.styles` block gives the rules. */
|
|
81
|
+
const GRAPHTY_WRITER = { ...WRITERS[0][1], tool: null };
|
|
82
|
+
/**
|
|
83
|
+
* The graph key holding the `graphty.styles` block: the block's name under the GML writer's rule for names that are
|
|
84
|
+
* not GML keys.
|
|
85
|
+
* @category Built-in formats
|
|
86
|
+
*/
|
|
87
|
+
export const GML_STYLE_BLOCK_KEY = mangleGmlKey(STYLE_BLOCK_NAME);
|
|
88
|
+
/** The key prefix of the per-element style values (`graphty.style.` under the same rule). */
|
|
89
|
+
const TAG_PREFIX = mangleGmlKey("graphty.style.");
|
|
90
|
+
/**
|
|
91
|
+
* The GML key of one style column's per-element values.
|
|
92
|
+
* @param target - nodes or edges
|
|
93
|
+
* @param key - the style column's key
|
|
94
|
+
* @returns the key
|
|
95
|
+
*/
|
|
96
|
+
function tagKey(target, key) {
|
|
97
|
+
return mangleGmlKey(styleTag(target, key));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A graph value as text, or null.
|
|
101
|
+
* @param snapshot - the graph
|
|
102
|
+
* @param name - the graph column
|
|
103
|
+
* @returns the text
|
|
104
|
+
*/
|
|
105
|
+
function graphText(snapshot, name) {
|
|
106
|
+
if (!snapshot.graph.has(name)) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const v = plainCell(snapshot.graph.value(name, 0));
|
|
110
|
+
if (typeof v === "string") {
|
|
111
|
+
return v;
|
|
112
|
+
}
|
|
113
|
+
return typeof v === "number" ? String(v) : null;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Who wrote a GML file: the `Creator` line (top level, or a key of the graph block as Gephi writes it), or graphty when
|
|
117
|
+
* the file holds a `graphty.styles` block.
|
|
118
|
+
* @param snapshot - the graph
|
|
119
|
+
* @returns the writer
|
|
120
|
+
*/
|
|
121
|
+
function writerOf(snapshot) {
|
|
122
|
+
if (snapshot.graph.has(GML_STYLE_BLOCK_KEY)) {
|
|
123
|
+
return GRAPHTY_WRITER;
|
|
124
|
+
}
|
|
125
|
+
const creator = snapshot.meta.creator ?? graphText(snapshot, "Creator") ?? "";
|
|
126
|
+
for (const [pattern, writer] of WRITERS) {
|
|
127
|
+
if (pattern.test(creator)) {
|
|
128
|
+
return writer;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return UNKNOWN_WRITER;
|
|
132
|
+
}
|
|
133
|
+
/** The edge's `arrow` key of the GML draft: which ends have an arrow. */
|
|
134
|
+
const ARROW_ENDS = new Map([
|
|
135
|
+
["none", ["none", "none"]],
|
|
136
|
+
["last", ["none", "triangle"]],
|
|
137
|
+
["first", ["triangle", "none"]],
|
|
138
|
+
["both", ["triangle", "triangle"]],
|
|
139
|
+
]);
|
|
140
|
+
/** OGDF's stroke types (`stipple`), by number. */
|
|
141
|
+
const OGDF_STROKES = ["none", "solid", "dashed", "dotted", "dash-dot", "dash-dot"];
|
|
142
|
+
/** OGDF's shape names the common table does not know. */
|
|
143
|
+
const OGDF_SHAPES = new Map([
|
|
144
|
+
["rect", "rectangle"],
|
|
145
|
+
["rhomb", "diamond"],
|
|
146
|
+
["trapeze", "trapezoid"],
|
|
147
|
+
["invtrapeze", "trapezoid"],
|
|
148
|
+
["invtriangle", "triangle"],
|
|
149
|
+
["invparallelogram", "parallelogram"],
|
|
150
|
+
]);
|
|
151
|
+
/** Keys only yEd writes in a label record: its `fill` is the label's background, not the text color. */
|
|
152
|
+
const YED_LABEL_KEYS = [
|
|
153
|
+
"outline",
|
|
154
|
+
"autoSizePolicy",
|
|
155
|
+
"model",
|
|
156
|
+
"configuration",
|
|
157
|
+
"borderDistance",
|
|
158
|
+
"modelName",
|
|
159
|
+
"modelPosition",
|
|
160
|
+
];
|
|
161
|
+
/** Cytoscape's legacy numbered arrows (`source_arrow 3`), read as Cytoscape reads them. */
|
|
162
|
+
const cytoscapeArrow = CYTOSCAPE_LEXICON.edge.get("targetArrow")?.[0]?.[1];
|
|
163
|
+
/**
|
|
164
|
+
* A short sample of a value for a note.
|
|
165
|
+
* @param raw - the value
|
|
166
|
+
* @returns its text, or "a record" for a record
|
|
167
|
+
*/
|
|
168
|
+
function sampleOf(raw) {
|
|
169
|
+
return typeof raw === "string" || typeof raw === "number"
|
|
170
|
+
? String(raw).slice(0, MAX_STYLE_VALUE_LENGTH)
|
|
171
|
+
: "a record";
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Whether a value is a GML record.
|
|
175
|
+
* @param v - the value
|
|
176
|
+
* @returns true for a non-array object
|
|
177
|
+
*/
|
|
178
|
+
function isRec(v) {
|
|
179
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The first defined value of some keys of a record.
|
|
183
|
+
* @param r - the record
|
|
184
|
+
* @param keys - the keys, in order of preference
|
|
185
|
+
* @returns the value, or undefined
|
|
186
|
+
*/
|
|
187
|
+
function first(r, ...keys) {
|
|
188
|
+
for (const k of keys) {
|
|
189
|
+
if (Object.hasOwn(r, k) && r[k] !== undefined) {
|
|
190
|
+
return r[k];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Reads a color and its alpha.
|
|
197
|
+
* @param raw - the value
|
|
198
|
+
* @param property - the color property
|
|
199
|
+
* @param opacity - its opacity property, or null
|
|
200
|
+
* @param writer - the writer
|
|
201
|
+
* @param put - receives the values
|
|
202
|
+
* @param at - the sites
|
|
203
|
+
*/
|
|
204
|
+
function readColor(raw, property, opacity, writer, put, at) {
|
|
205
|
+
if (raw === undefined) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const c = canonColor(raw, writer.spelling, at(property));
|
|
209
|
+
if (c === null) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
put(property, c.color);
|
|
213
|
+
const alpha = colorOpacity(c, null, at(property), opacity !== null);
|
|
214
|
+
if (opacity !== null) {
|
|
215
|
+
put(opacity, alpha);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* A stroke style: OGDF's numbered `stipple`, or a line type name.
|
|
220
|
+
* @param raw - the value
|
|
221
|
+
* @param kind - border or line style
|
|
222
|
+
* @param writer - the writer
|
|
223
|
+
* @param at - the site
|
|
224
|
+
* @returns the style, or null
|
|
225
|
+
*/
|
|
226
|
+
function strokeStyle(raw, kind, writer, at) {
|
|
227
|
+
if (raw === undefined) {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
if (writer.vocabulary === "ogdf") {
|
|
231
|
+
const stroke = OGDF_STROKES[Number(raw)];
|
|
232
|
+
if (stroke === undefined || stroke === "none") {
|
|
233
|
+
noteAt(at, STYLE_ISSUE.UNKNOWN_VALUE, sampleOf(raw));
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
return stroke;
|
|
237
|
+
}
|
|
238
|
+
return canonEnum(kind, raw, writer.spelling, at);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Reads one node's `graphics` record.
|
|
242
|
+
* @param g - the record
|
|
243
|
+
* @param writer - the writer
|
|
244
|
+
* @param put - receives the values
|
|
245
|
+
* @param at - the sites
|
|
246
|
+
*/
|
|
247
|
+
function readNodeGraphics(g, writer, put, at) {
|
|
248
|
+
const v = writer.vocabulary;
|
|
249
|
+
readNodeFill(g, writer, put, at);
|
|
250
|
+
readNodeOutline(g, writer, put, at);
|
|
251
|
+
put("borderStyle", strokeStyle(v === "ogdf" ? g.stipple : g.outlineStyle, "borderStyle", writer, at("borderStyle")));
|
|
252
|
+
put("width", g.w === undefined ? null : canonNumber(g.w, at("width")));
|
|
253
|
+
put("height", g.h === undefined ? null : canonNumber(g.h, at("height")));
|
|
254
|
+
if (g.type !== undefined) {
|
|
255
|
+
const raw = v === "ogdf" && typeof g.type === "string" ? (OGDF_SHAPES.get(g.type.toLowerCase()) ?? g.type) : g.type;
|
|
256
|
+
put("shape", canonEnum("shape", raw, writer.spelling, at("shape")));
|
|
257
|
+
}
|
|
258
|
+
else if (v === "yed" && typeof g.customconfiguration === "string") {
|
|
259
|
+
// yEd's flowchart palette keeps a node's shape as a configuration, not a `type`.
|
|
260
|
+
put("shape", flowchartShape(g.customconfiguration));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Reads the fill of one node's `graphics` record.
|
|
265
|
+
* @param g - the record
|
|
266
|
+
* @param writer - the writer
|
|
267
|
+
* @param put - receives the values
|
|
268
|
+
* @param at - the sites
|
|
269
|
+
*/
|
|
270
|
+
function readNodeFill(g, writer, put, at) {
|
|
271
|
+
if (writer.vocabulary === "yed" && Number(g.hasFill) === 0) {
|
|
272
|
+
noteAt(at("fill"), STYLE_ISSUE.NO_FILL, "hasFill 0");
|
|
273
|
+
put("fillOpacity", 0);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
readColor(g.fill, "fill", "fillOpacity", writer, put, at);
|
|
277
|
+
if (g.fill2 !== undefined) {
|
|
278
|
+
noteAt(at("fill"), STYLE_ISSUE.GRADIENT, sampleOf(g.fill2));
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Reads the outline color and width of one node's `graphics` record.
|
|
283
|
+
* @param g - the record
|
|
284
|
+
* @param writer - the writer
|
|
285
|
+
* @param put - receives the values
|
|
286
|
+
* @param at - the sites
|
|
287
|
+
*/
|
|
288
|
+
function readNodeOutline(g, writer, put, at) {
|
|
289
|
+
const v = writer.vocabulary;
|
|
290
|
+
if (v === "yed" && Number(g.hasOutline) === 0) {
|
|
291
|
+
put("borderWidth", 0);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
readColor(v === "ogdf" ? g.line : g.outline, "borderColor", null, writer, put, at);
|
|
295
|
+
const width = outlineWidthOf(g, v);
|
|
296
|
+
put("borderWidth", width === undefined ? null : canonNumber(width, at("borderWidth")));
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* The outline width of a node's `graphics` record, under the key its writer uses.
|
|
300
|
+
* @param g - the record
|
|
301
|
+
* @param v - the writer's vocabulary
|
|
302
|
+
* @returns the raw width, or undefined
|
|
303
|
+
*/
|
|
304
|
+
function outlineWidthOf(g, v) {
|
|
305
|
+
switch (v) {
|
|
306
|
+
case "yed":
|
|
307
|
+
return g.outlineWidth;
|
|
308
|
+
case "cytoscape":
|
|
309
|
+
return first(g, "outline_width", "width");
|
|
310
|
+
case "ogdf":
|
|
311
|
+
return g.lineWidth;
|
|
312
|
+
default:
|
|
313
|
+
return first(g, "width", "outlineWidth");
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Reads one edge's `graphics` record.
|
|
318
|
+
* @param g - the record
|
|
319
|
+
* @param writer - the writer
|
|
320
|
+
* @param put - receives the values
|
|
321
|
+
* @param at - the sites
|
|
322
|
+
*/
|
|
323
|
+
function readEdgeGraphics(g, writer, put, at) {
|
|
324
|
+
const v = writer.vocabulary;
|
|
325
|
+
readColor(g.fill, "color", "opacity", writer, put, at);
|
|
326
|
+
const width = v === "ogdf" ? first(g, "lineWidth", "width") : g.width;
|
|
327
|
+
put("width", width === undefined ? null : canonNumber(width, at("width")));
|
|
328
|
+
put("lineStyle", strokeStyle(v === "ogdf" ? g.stipple : g.style, "lineStyle", writer, at("lineStyle")));
|
|
329
|
+
if (typeof g.arrow === "string") {
|
|
330
|
+
const ends = ARROW_ENDS.get(g.arrow.trim().toLowerCase());
|
|
331
|
+
if (ends === undefined) {
|
|
332
|
+
noteAt(at("targetArrow"), STYLE_ISSUE.UNKNOWN_VALUE, g.arrow.slice(0, MAX_STYLE_VALUE_LENGTH));
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
put("sourceArrow", ends[0]);
|
|
336
|
+
put("targetArrow", ends[1]);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
for (const [keys, property] of [
|
|
340
|
+
[["sourceArrow", "source_arrow"], "sourceArrow"],
|
|
341
|
+
[["targetArrow", "target_arrow"], "targetArrow"],
|
|
342
|
+
]) {
|
|
343
|
+
const raw = first(g, ...keys);
|
|
344
|
+
if (raw === undefined) {
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
put(property, v === "cytoscape" && cytoscapeArrow !== undefined
|
|
348
|
+
? cytoscapeArrow(raw, at(property))
|
|
349
|
+
: canonEnum("arrow", raw, writer.spelling, at(property)));
|
|
350
|
+
}
|
|
351
|
+
if (v === "yed") {
|
|
352
|
+
readYedCurve(g, put);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Reads whether yEd draws an edge curved: `smoothBends` rounds the bends of its `Line`, whose points run from the
|
|
357
|
+
* source through the bends to the target, so a line of two points (or none) stays straight.
|
|
358
|
+
* @param g - the edge's `graphics` record
|
|
359
|
+
* @param put - receives the value
|
|
360
|
+
*/
|
|
361
|
+
function readYedCurve(g, put) {
|
|
362
|
+
if (g.smoothBends !== undefined) {
|
|
363
|
+
const points = isRec(g.Line) ? g.Line.point : undefined;
|
|
364
|
+
put("curved", Number(g.smoothBends) === 1 && Array.isArray(points) && points.length > 2);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Reads an element's label records: the first visible one with text; further visible ones are noted.
|
|
369
|
+
* @param raw - the `LabelGraphics` value (one record or several)
|
|
370
|
+
* @param writer - the writer
|
|
371
|
+
* @param put - receives the values
|
|
372
|
+
* @param at - the sites
|
|
373
|
+
*/
|
|
374
|
+
function readLabelGraphics(raw, writer, put, at) {
|
|
375
|
+
const visible = (Array.isArray(raw) ? raw : [raw]).filter((l) => isRec(l) && Number(l.visible) !== 0);
|
|
376
|
+
const lg = visible.at(0);
|
|
377
|
+
if (lg === undefined) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const extra = visible.slice(1).filter((l) => l.text !== undefined).length;
|
|
381
|
+
if (extra > 0) {
|
|
382
|
+
noteAt(at("label"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);
|
|
383
|
+
}
|
|
384
|
+
if (lg.text !== undefined) {
|
|
385
|
+
put("label", canonText(lg.text, at("label")));
|
|
386
|
+
}
|
|
387
|
+
// the GML draft's `fill` is the text color; yEd's is the label's background box, its `color` the text color
|
|
388
|
+
const yedLabel = writer.vocabulary === "yed" || YED_LABEL_KEYS.some((k) => Object.hasOwn(lg, k));
|
|
389
|
+
if (lg.color !== undefined) {
|
|
390
|
+
readColor(lg.color, "labelColor", null, writer, put, at);
|
|
391
|
+
}
|
|
392
|
+
else if (lg.fill !== undefined && !yedLabel) {
|
|
393
|
+
readColor(lg.fill, "labelColor", null, writer, put, at);
|
|
394
|
+
}
|
|
395
|
+
if (lg.fill !== undefined && yedLabel) {
|
|
396
|
+
noteAt(at("label"), STYLE_ISSUE.NOT_CARRIED, "label background");
|
|
397
|
+
}
|
|
398
|
+
readLabelFont(lg, put, at);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Reads a label record's font: its size, name, weight and slant.
|
|
402
|
+
* @param lg - the record
|
|
403
|
+
* @param put - receives the values
|
|
404
|
+
* @param at - the sites
|
|
405
|
+
*/
|
|
406
|
+
function readLabelFont(lg, put, at) {
|
|
407
|
+
put("labelSize", lg.fontSize === undefined ? null : canonNumber(lg.fontSize, at("labelSize")));
|
|
408
|
+
put("labelFont", lg.fontName === undefined ? null : canonText(lg.fontName, at("labelFont")));
|
|
409
|
+
const style = scalarText(lg.fontStyle, at("labelWeight"))?.trim().toLowerCase();
|
|
410
|
+
if (style !== undefined) {
|
|
411
|
+
const known = FONT_STYLES.get(style);
|
|
412
|
+
if (known === undefined) {
|
|
413
|
+
noteAt(at("labelWeight"), STYLE_ISSUE.UNKNOWN_VALUE, style.slice(0, MAX_STYLE_VALUE_LENGTH));
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
put("labelWeight", known[0]);
|
|
417
|
+
put("labelItalic", known[1]);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Reads one element: its `graphics` and `LabelGraphics`, and the `label` key where the writer draws it.
|
|
423
|
+
* @param target - nodes or edges
|
|
424
|
+
* @param g - the graphics value
|
|
425
|
+
* @param lg - the LabelGraphics value
|
|
426
|
+
* @param label - the `label` key's value
|
|
427
|
+
* @param writer - the writer
|
|
428
|
+
* @param put - receives the values
|
|
429
|
+
* @param at - the sites
|
|
430
|
+
*/
|
|
431
|
+
function readElement(target, g, lg, label, writer, put, at) {
|
|
432
|
+
let text = false;
|
|
433
|
+
const putLabel = (property, value) => {
|
|
434
|
+
text || (text = property === "label" && value !== null);
|
|
435
|
+
put(property, value);
|
|
436
|
+
};
|
|
437
|
+
if (isRec(g)) {
|
|
438
|
+
(target === "node" ? readNodeGraphics : readEdgeGraphics)(g, writer, put, at);
|
|
439
|
+
}
|
|
440
|
+
if (lg !== null && lg !== undefined) {
|
|
441
|
+
readLabelGraphics(lg, writer, putLabel, at);
|
|
442
|
+
}
|
|
443
|
+
// the GML draft draws the label key; Cytoscape reads it as the node's name, which its default style shows
|
|
444
|
+
const drawn = writer.vocabulary === "cytoscape" ? target === "node" : writer.labelKey && (isRec(g) || lg !== undefined);
|
|
445
|
+
if (!text && drawn && label !== null && label !== undefined) {
|
|
446
|
+
put("label", canonText(label, at("label")));
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* The value of a column, or undefined when the table has no such column.
|
|
451
|
+
* @param table - the node or edge table
|
|
452
|
+
* @param name - the column
|
|
453
|
+
* @param i - the row
|
|
454
|
+
* @returns the value
|
|
455
|
+
*/
|
|
456
|
+
function cellOf(table, name, i) {
|
|
457
|
+
if (!table.has(name)) {
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
const v = plainCell(table.value(name, i));
|
|
461
|
+
return v ?? undefined;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* A node's center: the `graphics` `x` and `y` the importer moved into the position column.
|
|
465
|
+
* @param snapshot - the graph
|
|
466
|
+
* @param i - the node's index
|
|
467
|
+
* @returns the center; NaN where the node has none
|
|
468
|
+
*/
|
|
469
|
+
function centerOf(snapshot, i) {
|
|
470
|
+
const column = snapshot.nodes.byRole("position");
|
|
471
|
+
const v = column?.isSet(i) === true ? column.value(i) : null;
|
|
472
|
+
return v === null ? [Number.NaN, Number.NaN] : [v[0], v[1]];
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* An edge's bends: the points of its `graphics` `Line` between the first and the last, which are where it leaves
|
|
476
|
+
* the source and meets the target.
|
|
477
|
+
* @param snapshot - the graph
|
|
478
|
+
* @param g - the edge's `graphics` value
|
|
479
|
+
* @param e - the edge's row
|
|
480
|
+
* @returns the `bends` value, or null without bends
|
|
481
|
+
*/
|
|
482
|
+
function lineBends(snapshot, g, e) {
|
|
483
|
+
const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;
|
|
484
|
+
if (!Array.isArray(raw) || raw.length < 3) {
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
const points = raw.slice(1, -1).map((p) => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));
|
|
488
|
+
return canonBends(centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e)), points, true);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Every element's values, read with a writer's vocabulary.
|
|
492
|
+
* @param snapshot - the graph
|
|
493
|
+
* @param writer - the writer
|
|
494
|
+
* @param notes - where problems are noted
|
|
495
|
+
* @param context - the work budget
|
|
496
|
+
* @returns the values per target, and whether anything was read
|
|
497
|
+
*/
|
|
498
|
+
function readValues(snapshot, writer, notes, context) {
|
|
499
|
+
let found = false;
|
|
500
|
+
const read = (target) => {
|
|
501
|
+
const table = target === "node" ? snapshot.nodes : snapshot.edges;
|
|
502
|
+
const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
|
|
503
|
+
const out = valueColumns(n);
|
|
504
|
+
if (!table.has("graphics") && !table.has("LabelGraphics") && writer.vocabulary !== "cytoscape") {
|
|
505
|
+
return out.values;
|
|
506
|
+
}
|
|
507
|
+
for (let i = 0; i < n; i++) {
|
|
508
|
+
context.budget.spend(target, 1);
|
|
509
|
+
const at = (property) => ({ notes, target, property, element: i, budget: context.budget });
|
|
510
|
+
readElement(target, cellOf(table, "graphics", i), cellOf(table, "LabelGraphics", i), cellOf(table, "label", i), writer, (property, value) => {
|
|
511
|
+
if (value !== null) {
|
|
512
|
+
found = true;
|
|
513
|
+
out.put(i, property, value);
|
|
514
|
+
}
|
|
515
|
+
}, at);
|
|
516
|
+
if (target === "edge") {
|
|
517
|
+
const bends = lineBends(snapshot, cellOf(table, "graphics", i), i);
|
|
518
|
+
if (bends !== null) {
|
|
519
|
+
found = true;
|
|
520
|
+
out.put(i, "bends", bends);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return out.values;
|
|
525
|
+
};
|
|
526
|
+
const node = read("node");
|
|
527
|
+
const edge = read("edge");
|
|
528
|
+
return { node, edge, found };
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* The `graphty.styles` block of a file graphty wrote, with the per-element values its rules read moved inside it from
|
|
532
|
+
* their `graphty_style_*` keys; the block as written when it is ignored anyway (graph-io then says why).
|
|
533
|
+
* @param snapshot - the graph
|
|
534
|
+
* @param text - the block's text
|
|
535
|
+
* @returns the block's text for graph-io to read
|
|
536
|
+
*/
|
|
537
|
+
function blockWithValues(snapshot, text) {
|
|
538
|
+
const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
|
|
539
|
+
if (!parsed.ok || parsed.block.values !== undefined) {
|
|
540
|
+
return text;
|
|
541
|
+
}
|
|
542
|
+
const node = tagValues(snapshot, "node", parsed.block.columns.node);
|
|
543
|
+
const edge = tagValues(snapshot, "edge", parsed.block.columns.edge);
|
|
544
|
+
if (node === null || edge === null) {
|
|
545
|
+
// a style column is missing: graph-io ignores the block with a note
|
|
546
|
+
return text;
|
|
547
|
+
}
|
|
548
|
+
const raw = JSON.parse(text);
|
|
549
|
+
return JSON.stringify({ ...raw, values: { node, edge } });
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* The per-element values of a target's style columns, read from their `graphty_style_*` keys.
|
|
553
|
+
* @param snapshot - the graph
|
|
554
|
+
* @param target - nodes or edges
|
|
555
|
+
* @param keys - the style columns the block names
|
|
556
|
+
* @returns the values by key, or null when a key is missing
|
|
557
|
+
*/
|
|
558
|
+
function tagValues(snapshot, target, keys) {
|
|
559
|
+
const table = target === "node" ? snapshot.nodes : snapshot.edges;
|
|
560
|
+
const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
|
|
561
|
+
const values = {};
|
|
562
|
+
for (const key of keys) {
|
|
563
|
+
const name = tagKey(target, key);
|
|
564
|
+
if (!table.has(name)) {
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
values[key] = Array.from({ length: n }, (_, i) => {
|
|
568
|
+
const v = plainCell(table.value(name, i));
|
|
569
|
+
return typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? v : null;
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
return values;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* The columns of a table that hold styles: the graphics records and graphty's per-element style values.
|
|
576
|
+
* @param table - the node or edge table
|
|
577
|
+
* @returns the column names
|
|
578
|
+
*/
|
|
579
|
+
function styleColumns(table) {
|
|
580
|
+
return [...table.names()].filter((c) => c === "graphics" || c === "LabelGraphics" || c.startsWith(TAG_PREFIX));
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* The styles of a GML file, read the way the program that wrote it draws them, with that program's defaults beneath:
|
|
584
|
+
* yEd, Cytoscape, Gephi and OGDF are recognized by the `Creator` line; igraph and every other writer get the GML
|
|
585
|
+
* draft's keys and no defaults. A file graphty wrote gives back its `graphty.styles` block.
|
|
586
|
+
* @param snapshot - the graph the import built
|
|
587
|
+
* @param context - the work budget
|
|
588
|
+
* @returns the styles, or null when the file has none
|
|
589
|
+
*/
|
|
590
|
+
export function gmlStyles(snapshot, context) {
|
|
591
|
+
const notes = new StyleNotes();
|
|
592
|
+
const writer = writerOf(snapshot);
|
|
593
|
+
const values = readValues(snapshot, writer, notes, context);
|
|
594
|
+
const blockText = graphText(snapshot, GML_STYLE_BLOCK_KEY);
|
|
595
|
+
const block = blockText === null ? null : blockWithValues(snapshot, blockText);
|
|
596
|
+
if (block !== null) {
|
|
597
|
+
exactFromBlock(snapshot, block, values);
|
|
598
|
+
}
|
|
599
|
+
if (writer.tool === null && !values.found && block === null) {
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
const gephi = writer.tool === "gephi"
|
|
603
|
+
? gephiRules(snapshot, values.node.fill, values.edge.color, context.budget, values.edge.width)
|
|
604
|
+
: { rules: [], columns: new Map() };
|
|
605
|
+
return {
|
|
606
|
+
canonical: true,
|
|
607
|
+
dialect: writer.dialect,
|
|
608
|
+
tool: writer.tool,
|
|
609
|
+
units: writer.units,
|
|
610
|
+
node: { values: values.node },
|
|
611
|
+
edge: { values: values.edge, rules: gephi.rules, columns: gephi.columns },
|
|
612
|
+
notes: notes.list(),
|
|
613
|
+
opacityInColor: true,
|
|
614
|
+
block,
|
|
615
|
+
// the graphics records and the per-element style values of a file graphty wrote hold styles, not data
|
|
616
|
+
readFrom: { node: styleColumns(snapshot.nodes), edge: styleColumns(snapshot.edges) },
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
// ============================================================ writing
|
|
620
|
+
/**
|
|
621
|
+
* What the GML writer holds natively: yEd GML `graphics` and `LabelGraphics`. The `graphty.styles` block and the
|
|
622
|
+
* per-element values its rules read are keys of the graph and of each element.
|
|
623
|
+
* @category Built-in formats
|
|
624
|
+
*/
|
|
625
|
+
export const GML_STYLE_CAPABILITIES = Object.freeze({
|
|
626
|
+
node: Object.freeze([
|
|
627
|
+
"fill",
|
|
628
|
+
"fillOpacity",
|
|
629
|
+
"borderColor",
|
|
630
|
+
"borderWidth",
|
|
631
|
+
"borderStyle",
|
|
632
|
+
"shape",
|
|
633
|
+
"width",
|
|
634
|
+
"height",
|
|
635
|
+
"label",
|
|
636
|
+
"labelColor",
|
|
637
|
+
"labelSize",
|
|
638
|
+
"labelFont",
|
|
639
|
+
"labelWeight",
|
|
640
|
+
"labelItalic",
|
|
641
|
+
]),
|
|
642
|
+
edge: Object.freeze([
|
|
643
|
+
"color",
|
|
644
|
+
"opacity",
|
|
645
|
+
"width",
|
|
646
|
+
"lineStyle",
|
|
647
|
+
"sourceArrow",
|
|
648
|
+
"targetArrow",
|
|
649
|
+
"curved",
|
|
650
|
+
"bends",
|
|
651
|
+
"label",
|
|
652
|
+
"labelColor",
|
|
653
|
+
"labelSize",
|
|
654
|
+
"labelFont",
|
|
655
|
+
"labelWeight",
|
|
656
|
+
"labelItalic",
|
|
657
|
+
]),
|
|
658
|
+
block: "native",
|
|
659
|
+
});
|
|
660
|
+
/** Every style key a reader here reads, per record: the writer replaces them all. */
|
|
661
|
+
const OWNED = {
|
|
662
|
+
node: new Set([
|
|
663
|
+
"fill",
|
|
664
|
+
"fill2",
|
|
665
|
+
"hasFill",
|
|
666
|
+
"outline",
|
|
667
|
+
"hasOutline",
|
|
668
|
+
"outlineWidth",
|
|
669
|
+
"outline_width",
|
|
670
|
+
"outlineStyle",
|
|
671
|
+
"width",
|
|
672
|
+
"line",
|
|
673
|
+
"lineWidth",
|
|
674
|
+
"stipple",
|
|
675
|
+
"w",
|
|
676
|
+
"h",
|
|
677
|
+
"type",
|
|
678
|
+
]),
|
|
679
|
+
edge: new Set([
|
|
680
|
+
"fill",
|
|
681
|
+
"width",
|
|
682
|
+
"lineWidth",
|
|
683
|
+
"style",
|
|
684
|
+
"stipple",
|
|
685
|
+
"arrow",
|
|
686
|
+
"sourceArrow",
|
|
687
|
+
"targetArrow",
|
|
688
|
+
"source_arrow",
|
|
689
|
+
"target_arrow",
|
|
690
|
+
"smoothBends",
|
|
691
|
+
]),
|
|
692
|
+
label: new Set(["text", "color", "fill", "fontSize", "fontName", "fontStyle", "visible"]),
|
|
693
|
+
};
|
|
694
|
+
/**
|
|
695
|
+
* A node's yEd `graphics` keys from its values.
|
|
696
|
+
* @param get - the node's values
|
|
697
|
+
* @param approximate - records approximations
|
|
698
|
+
* @returns the keys
|
|
699
|
+
*/
|
|
700
|
+
function nodeGraphics(get, approximate) {
|
|
701
|
+
const g = {};
|
|
702
|
+
const width = get("width");
|
|
703
|
+
const height = get("height");
|
|
704
|
+
if (typeof width === "number") {
|
|
705
|
+
g.w = width;
|
|
706
|
+
}
|
|
707
|
+
if (typeof height === "number") {
|
|
708
|
+
g.h = height;
|
|
709
|
+
}
|
|
710
|
+
const shape = get("shape");
|
|
711
|
+
if (typeof shape === "string") {
|
|
712
|
+
const w = yedValue(YED_SHAPES, shape, shape === "vee" ? "triangle" : "rectangle");
|
|
713
|
+
if (!w.exact) {
|
|
714
|
+
approximate("shape", shape);
|
|
715
|
+
}
|
|
716
|
+
g.type = w.value;
|
|
717
|
+
}
|
|
718
|
+
const fill = get("fill");
|
|
719
|
+
const fillOpacity = get("fillOpacity");
|
|
720
|
+
if (typeof fill === "string") {
|
|
721
|
+
g.fill = yedColor(fill, fillOpacity);
|
|
722
|
+
}
|
|
723
|
+
else if (fillOpacity === 0) {
|
|
724
|
+
g.hasFill = 0;
|
|
725
|
+
}
|
|
726
|
+
const borderColor = get("borderColor");
|
|
727
|
+
const borderWidth = get("borderWidth");
|
|
728
|
+
const borderStyle = get("borderStyle");
|
|
729
|
+
if (typeof borderColor === "string") {
|
|
730
|
+
g.outline = borderColor.toUpperCase();
|
|
731
|
+
}
|
|
732
|
+
if (typeof borderStyle === "string") {
|
|
733
|
+
const w = yedValue(YED_LINES, borderStyle, "line");
|
|
734
|
+
if (!w.exact) {
|
|
735
|
+
approximate("borderStyle", borderStyle);
|
|
736
|
+
}
|
|
737
|
+
g.outlineStyle = w.value;
|
|
738
|
+
}
|
|
739
|
+
if (borderWidth === 0) {
|
|
740
|
+
g.hasOutline = 0;
|
|
741
|
+
}
|
|
742
|
+
else if (typeof borderWidth === "number") {
|
|
743
|
+
g.outlineWidth = borderWidth;
|
|
744
|
+
}
|
|
745
|
+
return g;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* An edge's yEd `graphics` keys from its values.
|
|
749
|
+
* @param get - the edge's values
|
|
750
|
+
* @param approximate - records approximations
|
|
751
|
+
* @returns the keys
|
|
752
|
+
*/
|
|
753
|
+
function edgeGraphics(get, approximate) {
|
|
754
|
+
const g = {};
|
|
755
|
+
const color = get("color");
|
|
756
|
+
if (typeof color === "string") {
|
|
757
|
+
g.fill = yedColor(color, get("opacity"));
|
|
758
|
+
}
|
|
759
|
+
const width = get("width");
|
|
760
|
+
if (typeof width === "number") {
|
|
761
|
+
g.width = width;
|
|
762
|
+
}
|
|
763
|
+
const lineStyle = get("lineStyle");
|
|
764
|
+
if (typeof lineStyle === "string") {
|
|
765
|
+
g.style = yedSpelled(YED_LINES, lineStyle, lineStyle === "long-dash" ? "dashed" : "line", "lineStyle", approximate);
|
|
766
|
+
}
|
|
767
|
+
for (const property of ["sourceArrow", "targetArrow"]) {
|
|
768
|
+
const arrow = get(property);
|
|
769
|
+
if (typeof arrow === "string") {
|
|
770
|
+
g[property] = yedSpelled(YED_ARROWS, arrow, "standard", property, approximate);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
const curved = get("curved");
|
|
774
|
+
if (typeof curved === "boolean") {
|
|
775
|
+
g.smoothBends = curved ? 1 : 0;
|
|
776
|
+
}
|
|
777
|
+
return g;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* An element's yEd `LabelGraphics` keys from its values, or null when it has no label text.
|
|
781
|
+
* @param get - the element's values
|
|
782
|
+
* @returns the keys
|
|
783
|
+
*/
|
|
784
|
+
function labelGraphics(get) {
|
|
785
|
+
const text = get("label");
|
|
786
|
+
if (typeof text !== "string" || text.trim().length === 0) {
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
const lg = { text };
|
|
790
|
+
const color = get("labelColor");
|
|
791
|
+
if (typeof color === "string") {
|
|
792
|
+
lg.color = color.toUpperCase();
|
|
793
|
+
}
|
|
794
|
+
const size = get("labelSize");
|
|
795
|
+
if (typeof size === "number") {
|
|
796
|
+
lg.fontSize = size;
|
|
797
|
+
}
|
|
798
|
+
const font = get("labelFont");
|
|
799
|
+
if (typeof font === "string") {
|
|
800
|
+
lg.fontName = font;
|
|
801
|
+
}
|
|
802
|
+
const weight = get("labelWeight");
|
|
803
|
+
const italic = get("labelItalic");
|
|
804
|
+
if (weight !== null || italic !== null) {
|
|
805
|
+
const style = (weight === "bold" ? "bold" : "") + (italic === true ? "italic" : "");
|
|
806
|
+
lg.fontStyle = style.length === 0 ? "plain" : style;
|
|
807
|
+
}
|
|
808
|
+
return lg;
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* A record with the style keys replaced: the kept keys of the old record, then the written ones.
|
|
812
|
+
* @param old - the record the element had, or anything else
|
|
813
|
+
* @param owned - the style keys
|
|
814
|
+
* @param written - the new style keys
|
|
815
|
+
* @returns the record, or undefined (an unset cell) when it is empty
|
|
816
|
+
*/
|
|
817
|
+
function merged(old, owned, written) {
|
|
818
|
+
const out = {};
|
|
819
|
+
if (isRec(old)) {
|
|
820
|
+
for (const [k, v] of Object.entries(old)) {
|
|
821
|
+
if (!owned.has(k)) {
|
|
822
|
+
out[k] = v;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
Object.assign(out, written);
|
|
827
|
+
return Object.keys(out).length === 0 ? undefined : out;
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* An element's `LabelGraphics` value with its first label's style keys replaced; further labels are kept.
|
|
831
|
+
* @param old - the value the element had
|
|
832
|
+
* @param written - the new label keys, or null for no label
|
|
833
|
+
* @returns the value, or undefined (an unset cell)
|
|
834
|
+
*/
|
|
835
|
+
function mergedLabels(old, written) {
|
|
836
|
+
const labels = Array.isArray(old) ? old : [old];
|
|
837
|
+
const head = merged(labels[0], OWNED.label, written ?? {});
|
|
838
|
+
const rest = labels.slice(1).filter((l) => l !== null && l !== undefined);
|
|
839
|
+
if (rest.length === 0) {
|
|
840
|
+
return head;
|
|
841
|
+
}
|
|
842
|
+
return head === undefined ? rest : [head, ...rest];
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Each element's values of the properties the writer writes, as a getter per element.
|
|
846
|
+
* @param picture - each element's value of a property
|
|
847
|
+
* @param target - nodes or edges
|
|
848
|
+
* @returns the getter
|
|
849
|
+
*/
|
|
850
|
+
function getter(picture, target) {
|
|
851
|
+
const columns = new Map();
|
|
852
|
+
for (const p of GML_STYLE_CAPABILITIES[target]) {
|
|
853
|
+
columns.set(p, picture(target, p));
|
|
854
|
+
}
|
|
855
|
+
return (i) => (property) => columns.get(property)?.[i] ?? null;
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* For a file graphty wrote: where a value read from the graphics is what the writer writes for the block's own value
|
|
859
|
+
* (a pentagon written as a rectangle, an opacity rounded to 255 steps), the block's exact value is the truth, so a
|
|
860
|
+
* re-import gives back the same rules; a value another program changed since stays the truth.
|
|
861
|
+
* @param snapshot - the graph
|
|
862
|
+
* @param text - the block's text
|
|
863
|
+
* @param read - the values read, changed in place
|
|
864
|
+
* @param read.node - the node values
|
|
865
|
+
* @param read.edge - the edge values
|
|
866
|
+
*/
|
|
867
|
+
function exactFromBlock(snapshot, text, read) {
|
|
868
|
+
const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
|
|
869
|
+
const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "gml") : null;
|
|
870
|
+
if (ex === null) {
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
const notes = new StyleNotes();
|
|
874
|
+
for (const target of ["node", "edge"]) {
|
|
875
|
+
const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
|
|
876
|
+
const get = getter((t, p) => resolveStyles(ex, t, p, snapshot), target);
|
|
877
|
+
const values = read[target];
|
|
878
|
+
for (let i = 0; i < n; i++) {
|
|
879
|
+
const want = get(i);
|
|
880
|
+
const back = writtenAndReadBack(target, want, notes);
|
|
881
|
+
for (const property of GML_STYLE_CAPABILITIES[target]) {
|
|
882
|
+
const native = values[property]?.[i] ?? null;
|
|
883
|
+
const w = want(property);
|
|
884
|
+
if (native !== w && native === (back.get(property) ?? null)) {
|
|
885
|
+
values[property] ?? (values[property] = new Array(n).fill(null));
|
|
886
|
+
values[property][i] = w;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* An element's values written as the writer writes them and read back as the reader reads them.
|
|
894
|
+
* @param target - nodes or edges
|
|
895
|
+
* @param want - its values
|
|
896
|
+
* @param notes - a scratch for the notes the round trip makes
|
|
897
|
+
* @returns the values read back, by property
|
|
898
|
+
*/
|
|
899
|
+
function writtenAndReadBack(target, want, notes) {
|
|
900
|
+
const ignore = () => undefined;
|
|
901
|
+
const g = target === "node" ? nodeGraphics(want, ignore) : edgeGraphics(want, ignore);
|
|
902
|
+
const back = new Map();
|
|
903
|
+
readElement(target, g, labelGraphics(want) ?? undefined, undefined, GRAPHTY_WRITER, (property, value) => {
|
|
904
|
+
if (value !== null) {
|
|
905
|
+
back.set(property, value);
|
|
906
|
+
}
|
|
907
|
+
}, (property) => ({ notes, target, property }));
|
|
908
|
+
return back;
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Works out a GML export with styles: every node's and edge's `graphics` and `LabelGraphics` records get yEd's keys
|
|
912
|
+
* for what graphty draws in place of every style key they had (positions, bends and other keys stay), the
|
|
913
|
+
* `graphty.styles` block becomes the graph key `graphty_styles` and the per-element values its rules read become
|
|
914
|
+
* element keys. Should two style columns map to one key, the values go inside the block instead.
|
|
915
|
+
* @param snapshot - the graph handed to the exporter
|
|
916
|
+
* @param input - the styles, or undefined when none are written
|
|
917
|
+
* @returns the styled export, or null without styles
|
|
918
|
+
*/
|
|
919
|
+
export function gmlStyledExport(snapshot, input) {
|
|
920
|
+
if (input === undefined) {
|
|
921
|
+
return null;
|
|
922
|
+
}
|
|
923
|
+
const approximated = new StyleApproximations();
|
|
924
|
+
const out = snapshot.withColumns();
|
|
925
|
+
const renames = [];
|
|
926
|
+
for (const target of ["node", "edge"]) {
|
|
927
|
+
const table = target === "node" ? out.nodes : out.edges;
|
|
928
|
+
writeGraphicsColumns(snapshot, input, target, table, approximated);
|
|
929
|
+
// the per-element style values of an earlier write go; a data column the rules read, or any other whose key
|
|
930
|
+
// would read back as a style value, is renamed out of the keys the style values take
|
|
931
|
+
const read = dataRead(input.rules.styles.rules, target);
|
|
932
|
+
for (const name of table.names().filter((c) => mangleGmlKey(c).startsWith(TAG_PREFIX))) {
|
|
933
|
+
const col = table.get(name);
|
|
934
|
+
table.remove(name);
|
|
935
|
+
if (col !== null && !(name.startsWith(TAG_PREFIX) && !read.has(name))) {
|
|
936
|
+
renames.push(renameDataColumn(table, target, name, col));
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
let { block } = input;
|
|
941
|
+
const keys = [...input.rules.columns.node.keys()].map((k) => tagKey("node", k));
|
|
942
|
+
const edgeKeys = [...input.rules.columns.edge.keys()].map((k) => tagKey("edge", k));
|
|
943
|
+
if (new Set(keys).size !== keys.length || new Set(edgeKeys).size !== edgeKeys.length) {
|
|
944
|
+
block = writeStyleBlock(input.rules, { inlineColumns: true, snapshot });
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
setTagColumns(out, input);
|
|
948
|
+
}
|
|
949
|
+
out.graph.set(GML_STYLE_BLOCK_KEY, [block], { dtype: "string" });
|
|
950
|
+
const notes = [
|
|
951
|
+
...renames,
|
|
952
|
+
...(block === input.block ? [] : styleBlockLosses(block, input.rules.styles.rules.length, "size")),
|
|
953
|
+
...approximated.notes("yEd's GML"),
|
|
954
|
+
];
|
|
955
|
+
return { snapshot: out, notes };
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Writes every element's `graphics` and `LabelGraphics` records of a target with yEd's keys for what graphty draws,
|
|
959
|
+
* keeping the keys that are not style keys.
|
|
960
|
+
* @param snapshot - the graph handed to the exporter
|
|
961
|
+
* @param input - the styles
|
|
962
|
+
* @param target - nodes or edges
|
|
963
|
+
* @param table - the target's table being written, changed in place
|
|
964
|
+
* @param approximated - where approximations are counted
|
|
965
|
+
*/
|
|
966
|
+
function writeGraphicsColumns(snapshot, input, target, table, approximated) {
|
|
967
|
+
const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
|
|
968
|
+
const approximate = (property, value) => {
|
|
969
|
+
approximated.add(target, property, value);
|
|
970
|
+
};
|
|
971
|
+
const get = getter((t, p) => input.picture(t, p), target);
|
|
972
|
+
const graphics = [];
|
|
973
|
+
const labels = [];
|
|
974
|
+
for (let i = 0; i < n; i++) {
|
|
975
|
+
const g = target === "node" ? nodeGraphics(get(i), approximate) : edgeGraphics(get(i), approximate);
|
|
976
|
+
if (target === "edge") {
|
|
977
|
+
const line = bendsLine(snapshot, get(i)("bends"), i);
|
|
978
|
+
if (line !== null) {
|
|
979
|
+
g.Line = line;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
graphics.push(merged(cellOf(table, "graphics", i), OWNED[target], g));
|
|
983
|
+
labels.push(mergedLabels(cellOf(table, "LabelGraphics", i), labelGraphics(get(i))));
|
|
984
|
+
}
|
|
985
|
+
for (const [name, cells] of [
|
|
986
|
+
["graphics", graphics],
|
|
987
|
+
["LabelGraphics", labels],
|
|
988
|
+
]) {
|
|
989
|
+
if (cells.some((c) => c !== undefined)) {
|
|
990
|
+
table.set(name, cells, { dtype: "json", nullable: true });
|
|
991
|
+
}
|
|
992
|
+
else if (table.has(name)) {
|
|
993
|
+
table.remove(name);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* An edge's `Line` from its `bends` value: the node centers it is written between, with the bends placed between them,
|
|
999
|
+
* so the bends read back as written.
|
|
1000
|
+
* @param snapshot - the graph handed to the exporter
|
|
1001
|
+
* @param bends - the edge's `bends` value
|
|
1002
|
+
* @param e - the edge's row
|
|
1003
|
+
* @returns the `Line` record, or null without a value or without both centers
|
|
1004
|
+
*/
|
|
1005
|
+
function bendsLine(snapshot, bends, e) {
|
|
1006
|
+
const source = centerOf(snapshot, snapshot.edgeSource(e));
|
|
1007
|
+
const target = centerOf(snapshot, snapshot.edgeTarget(e));
|
|
1008
|
+
const points = typeof bends === "string" ? bendsToPoints(source, target, bends, true) : null;
|
|
1009
|
+
if (points === null || ![...source, ...target].every(Number.isFinite)) {
|
|
1010
|
+
return null;
|
|
1011
|
+
}
|
|
1012
|
+
return { point: [source, ...points, target].map(([x, y]) => ({ x, y })) };
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Writes a data column under a name out of the keys the style values take.
|
|
1016
|
+
* @param table - the table, changed in place
|
|
1017
|
+
* @param target - nodes or edges
|
|
1018
|
+
* @param name - the column's name
|
|
1019
|
+
* @param col - the column
|
|
1020
|
+
* @returns the note saying so
|
|
1021
|
+
*/
|
|
1022
|
+
function renameDataColumn(table, target, name, col) {
|
|
1023
|
+
let renamed = `data_${name}`;
|
|
1024
|
+
let k = 2;
|
|
1025
|
+
while (table.has(renamed)) {
|
|
1026
|
+
renamed = `data_${name}_${String(k)}`;
|
|
1027
|
+
k++;
|
|
1028
|
+
}
|
|
1029
|
+
table.set(renamed, col);
|
|
1030
|
+
return Object.freeze({
|
|
1031
|
+
code: KEY_MANGLED_CODE,
|
|
1032
|
+
message: `${target} column "${name}" is written as "${renamed}": keys starting with ${TAG_PREFIX} hold graphty's style values`,
|
|
1033
|
+
column: name,
|
|
1034
|
+
count: null,
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Sets the per-element values the rules read as element keys.
|
|
1039
|
+
* @param out - the graph, changed in place
|
|
1040
|
+
* @param input - the styles
|
|
1041
|
+
*/
|
|
1042
|
+
function setTagColumns(out, input) {
|
|
1043
|
+
for (const target of ["node", "edge"]) {
|
|
1044
|
+
const table = target === "node" ? out.nodes : out.edges;
|
|
1045
|
+
for (const [key, col] of input.rules.columns[target]) {
|
|
1046
|
+
const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));
|
|
1047
|
+
const text = kinds.size > 1 || kinds.has("string");
|
|
1048
|
+
let dtype = kinds.has("boolean") ? "bool" : "f64";
|
|
1049
|
+
if (text) {
|
|
1050
|
+
dtype = "string";
|
|
1051
|
+
}
|
|
1052
|
+
table.set(tagKey(target, key), text ? col.map((v) => (v === null ? null : String(v))) : col, { dtype });
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
//# sourceMappingURL=styles.js.map
|