{"id":15761423,"url":"https://github.com/rpgove/greadability","last_synced_at":"2025-04-30T22:24:45.873Z","repository":{"id":229107658,"uuid":"74491686","full_name":"rpgove/greadability","owner":"rpgove","description":"Graph layout readability metrics.","archived":false,"fork":false,"pushed_at":"2018-11-20T21:37:08.000Z","size":193,"stargazers_count":77,"open_issues_count":3,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-11T11:10:11.664Z","etag":null,"topics":["graph","javascript","visualization"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rpgove.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-11-22T16:27:53.000Z","updated_at":"2024-07-20T21:03:34.000Z","dependencies_parsed_at":"2024-03-22T04:27:59.535Z","dependency_job_id":"d3692fc1-c1ef-47ab-b933-725c8e85f568","html_url":"https://github.com/rpgove/greadability","commit_stats":null,"previous_names":["rpgove/greadability"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpgove%2Fgreadability","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpgove%2Fgreadability/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpgove%2Fgreadability/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpgove%2Fgreadability/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rpgove","download_url":"https://codeload.github.com/rpgove/greadability/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251790583,"owners_count":21644241,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graph","javascript","visualization"],"created_at":"2024-10-04T11:02:41.597Z","updated_at":"2025-04-30T22:24:45.847Z","avatar_url":"https://github.com/rpgove.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Greadability.js\n\n**Greadability.js** is a JavaScript library for computing global **g**raph **readability** metrics on graph layouts. These readability metrics help us answer questions like, which layout is better? Or, has the layout converged, or should it continue running?\n\nAt present, Greadability.js includes four global graph readability metrics:\n\n* *Edge crossings* measures the fraction of edges that cross (intersect) out of an approximate maximum number that can cross.\n* *Edge crossing angle* measures the mean deviation of edge crossing angles from the ideal edge crossing angle (70 degrees).\n* *Angular resolution (minimum)* measures the mean deviation of adjacent incident edge angles from the ideal minimum angles (360 degrees divided by the degree of that node).\n* *Angular resoluction (deviation)* measures the average deviation of angles between incident\nedges on each vertex.\n\nEach is a number in the range [0, 1] with higher numbers indicating better layouts. You can use this to measure when a graph layout algorithm has stopped improving (i.e. when it has [converged](https://bl.ocks.org/rpgove/8c8b08cc0ae1e1e969f5d2904a6a0e26)), or to find [good graph layout algorithm parameters](https://bl.ocks.org/rpgove/553450ed8ef2a48acd4121a85653d880).\n\n[\u003cimg alt=\"Force Directed Layout Quality Convergence\" src=\"https://raw.githubusercontent.com/rpgove/greadability/master/img/convergence.png\" width=\"400\" height=\"201\"\u003e](https://bl.ocks.org/rpgove/8c8b08cc0ae1e1e969f5d2904a6a0e26)[\u003cimg alt=\"Automatically Finding Better Force Directed Layout Parameters (10x10 Grid)\" src=\"https://raw.githubusercontent.com/rpgove/greadability/master/img/bestparameters.png\" width=\"412\" height=\"281\"\u003e](https://bl.ocks.org/rpgove/553450ed8ef2a48acd4121a85653d880)\n\nTo use this module, create a layout for a graph (e.g. using [D3.js](https://d3js.org)) so that each vertex (also known as a *node*) has `x` and `y` properties for its coordinates and each edge (also known as a *link*) has `source` and `target` properties that point to vertices.\n\nIf you use this library please cite the following paper for the definition of the angular resolution (deviation) metric and the proof that it yields values in the range [0, 1]:\n\nRobert Gove. \"It Pays to Be Lazy: Reusing Force Approximations to Compute Better Graph Layouts Faster.\" Proceedings of Forum Media Technology, 2018. [Preprint PDF.](https://osf.io/wgzn5/)\n\nFor the other metrics and a general discussion of graph layout readability metrics, see Dunne *et al* and [their earlier tech report](http://www.cs.umd.edu/hcil/trs/2009-13/2009-13.pdf):\n\nC. Dunne, S. I. Ross, B. Shneiderman, and M. Martino. \"Readability metric feedback for aiding node-link visualization designers,\" IBM Journal of Research and Development, 59(2/3) pages 14:1--14:16, 2015.\n\n## Installing\n\nDownload the latest version from the [Greadability.js GitHub repository](https://github.com/rpgove/greadability/releases).\n\nYou can then use it in a webpage, like this:\n\n```html\n\u003cscript src=\"greadability.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n\nvar simulation = d3.forceSimulation()\n    .force(\"link\", d3.forceLink().id(function(d) { return d.id; }).links(graph.links))\n    .force(\"charge\", d3.forceManyBody())\n    .nodes(graph.nodes)\n    .on(\"end\", computeReadability);\n\nfunction computeReadability () {\n\tvar nodes = simulation.nodes();\n\tvar links = simulation.force(\"link\").links();\n\tconsole.log(greadability.greadability(nodes, links));\n}\n\n\u003c/script\u003e\n```\n\nOr similarly in Node.js:\n\n```js\nconst greadability = require('./greadability.js');\n\nvar simulation = d3.forceSimulation()\n    .force(\"link\", d3.forceLink().id(function(d) { return d.id; }).links(graph.links))\n    .force(\"charge\", d3.forceManyBody())\n    .nodes(graph.nodes)\n    .on(\"end\", computeReadability);\n\nfunction computeReadability () {\n\tvar nodes = simulation.nodes();\n\tvar links = simulation.force(\"link\").links();\n\tconsole.log(greadability.greadability(nodes, links));\n}\n```\n\n## API Reference\n\n\u003ca name=\"greadability\" href=\"#greadability\"\u003e#\u003c/a\u003e \u003ci\u003egreadability\u003c/i\u003e.\u003cb\u003egreadability\u003c/b\u003e(\u003ci\u003enodes\u003c/i\u003e, \u003ci\u003elinks\u003c/i\u003e[, \u003ci\u003eid\u003c/i\u003e]) [\u003c\u003e](https://github.com/rpgove/greadability/blob/master/greadability.js#L7 \"Source\")\n\nComputes the readability metrics of the graph formed by the *nodes* and *links*. Each node in *nodes* must have `x` and `y` attributes specifying each node's position. This function returns an object with the readability metrics as the properties and values:\n\n```javascript\n{\n\tcrossing: 1,\n\tcrossingAngle: 0.7,\n\tangularResolutionMin: 0.34,\n\tangularResolutionDev: 0.56\n}\n```\n\nIf *id* is specified, sets the node id accessor to the specified function. If *id* is not specified, uses the default node id accessor, which defaults to the node's index. Note that if each link's `source` and `target` properties are objects, then the node id accessor is not used. This is the same behavior as the forceSimulation in D3.js.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frpgove%2Fgreadability","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frpgove%2Fgreadability","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frpgove%2Fgreadability/lists"}