From 614718a299b1319123170440dafc10d3f707acd3 Mon Sep 17 00:00:00 2001 From: Alex Bigelow Date: Wed, 13 Mar 2024 11:08:31 -0700 Subject: [PATCH 1/5] Add a draft Who We Are page --- _quarto.yml | 4 +- components/nodeLinkDiagram.ojs | 160 +++++++++++ data/people.json | 504 +++++++++++++++++++++++++++++++-- data/toyPeople.json | 66 +++++ theme.scss | 2 +- whoWeAre.qmd | 20 +- 6 files changed, 724 insertions(+), 32 deletions(-) create mode 100644 components/nodeLinkDiagram.ojs create mode 100644 data/toyPeople.json diff --git a/_quarto.yml b/_quarto.yml index 7e95c71..8d2da68 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -11,8 +11,8 @@ website: text: Home - href: index.qmd#events text: Events - # - href: whoWeAre.qmd - # text: Who We Are + - href: whoWeAre.qmd + text: Who We Are body-footer: | ::: {.footer} ![ResBaz Logo](/img/logos/ResBazAZrectanglelogo-small.png) \ diff --git a/components/nodeLinkDiagram.ojs b/components/nodeLinkDiagram.ojs new file mode 100644 index 0000000..0fc0936 --- /dev/null +++ b/components/nodeLinkDiagram.ojs @@ -0,0 +1,160 @@ +people = FileAttachment("data/people.json").json(); + +function nodeLinkDiagram () { + const height = width * 0.6; + + const personNodeRadius = 25; + + const teamNodeRadius = 75; + + const strokeWeight = 5; + + const weeklyTeams = new Set([ + 'coffee_and_code', + 'hacky_hour' + ]); + + const teamColors = d3.scaleOrdinal(['WEEKLY', 'FESTIVAL'], ['#ea5a2a', '#1e58ac']); + + const peopleById = Object.fromEntries( + people.data.organization.membersWithRole.nodes.map((person) => [ + person.id, + { + ...person, + type: "PERSON" + } + ]) + ); + const nodes = Object.values(peopleById); + const links = []; + people.data.organization.teams.nodes.forEach((team) => { + const teamId = team.name.toLowerCase().replace(/\s+/g, "_"); + nodes.push({ id: teamId, name: team.name, type: weeklyTeams.has(teamId) ? "WEEKLY" : "FESTIVAL" }); + team.members.nodes.forEach((member) => { + links.push({ source: member.id, target: teamId }); + }); + }); + + const simulation = d3 + .forceSimulation(nodes) + .force( + "link", + d3.forceLink(links).id((d) => d.id) + ) + .force( + "charge", + d3.forceManyBody().strength(-30 * (personNodeRadius + teamNodeRadius)) + ) + .force("center", d3.forceCenter(width / 2, height / 2)); + + const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]); + + let draggedNode = null; + let selectedNode = null; + + function mousedown(_, node) { + if (draggedNode) { + return; + } + simulation.alphaTarget(0.3).restart(); + draggedNode = selectedNode = node.id; + node.fx = node.x; + node.fy = node.y; + } + + function mousemove(event, node) { + if (!draggedNode) { + return; + } + const bounds = svg.node().getBoundingClientRect(); + node.fx = event.x - bounds.left; + node.fy = event.y - bounds.top; + } + + function mouseup(_, event) { + if (!draggedNode) { + return; + } + draggedNode = null; + simulation.alphaTarget(0); + node.fx = null; + node.fy = null; + } + + const link = svg + .append("g") + .attr("stroke", "#999") + .attr("stroke-opacity", 0.6) + .selectAll("line") + .data(links) + .join("line") + .attr("stroke-width", strokeWeight); + + const node = svg + .append("g") + .selectAll("g.node") + .data(nodes) + .join("g") + .classed("node", true) + // d3.drag() does weird things with quarto's minified version of d3... + // plus, this lets us control clicking vs dragging ourselves + .on('mousedown', mousedown) + .on('mousemove', mousemove) + .on('mouseup', mouseup); + + const teamCircle = node + .filter((d) => d.type !== "PERSON") + .append("circle") + .attr("r", teamNodeRadius) + .style("fill", d => teamColors(d.type)); + + const clipPath = node + .filter((d) => d.type === "PERSON") + .append("clipPath") + .attr("id", (d) => d.id) + .append("circle") + .attr("id", (d) => d.id) + .attr("r", personNodeRadius); + + // Append images + const profileImage = node + .filter((d) => d.type === "PERSON") + .append("image") + .attr("href", (d) => d.avatarUrl) + .attr("x", (d) => -personNodeRadius) + .attr("y", (d) => -personNodeRadius) + .attr("width", personNodeRadius * 2) + .attr("height", personNodeRadius * 2) + .attr("clip-path", (d) => `url(#${d.id})`) + .attr("preserveAspectRatio", "xMidYMin slice"); + + const text = node + .append("text") + .attr("class", "node_label") + .attr("y", (d) => + d.type === "PERSON" ? `${personNodeRadius}px` : "0.5em" + ) + .style("fill", (d) => (d.type === "PERSON" ? "black" : "white")) + .style("dominant-baseline", (d) => + d.type === "PERSON" ? "hanging" : "bottom" + ) + .style("text-anchor", "middle") + .style("font-size", "10pt") + .text((d) => d.name); + + node.append("title").text((d) => d.id); + + simulation.on("tick", () => { + link + .attr("x1", (d) => d.source.x) + .attr("y1", (d) => d.source.y) + .attr("x2", (d) => d.target.x) + .attr("y2", (d) => d.target.y); + + node.attr("transform", (d) => "translate(" + d.x + "," + d.y + ")"); + }); + + // invalidation.then(() => simulation.stop()); + + return svg.node(); +} \ No newline at end of file diff --git a/data/people.json b/data/people.json index 4ada482..1023052 100644 --- a/data/people.json +++ b/data/people.json @@ -3,20 +3,72 @@ "organization": { "teams": { "nodes": [ + { + "name": "Website Team", + "members": { + "nodes": [ + { "id": "MDQ6VXNlcjc0MjYzMw==" }, + { "id": "MDQ6VXNlcjEyMTU4NzM=" }, + { "id": "MDQ6VXNlcjE5Mzk4MTM=" }, + { "id": "MDQ6VXNlcjcwODIwMjU=" }, + { "id": "MDQ6VXNlcjExMDIzMzE3" }, + { "id": "MDQ6VXNlcjEyMDIyMDc2" }, + { "id": "MDQ6VXNlcjIxMTI5NjM5" }, + { "id": "MDQ6VXNlcjM4OTYyMjQz" }, + { "id": "U_kgDOBef8kg" } + ] + } + }, + { + "name": "Governance Task Force", + "members": { + "nodes": [ + { "id": "MDQ6VXNlcjc0MjYzMw==" }, + { "id": "MDQ6VXNlcjEyMTU4NzM=" }, + { "id": "MDQ6VXNlcjIxMTI5NjM5" }, + { "id": "MDQ6VXNlcjU2NzAyNjAw" }, + { "id": "U_kgDOBef8kg" } + ] + } + }, + { + "name": "Festival2024", + "members": { + "nodes": [ + { "id": "MDQ6VXNlcjc0MjYzMw==" }, + { "id": "MDQ6VXNlcjEyMTU4NzM=" }, + { "id": "MDQ6VXNlcjE5Mzk4MTM=" }, + { "id": "MDQ6VXNlcjM4ODMyNDE=" }, + { "id": "MDQ6VXNlcjEyNjkxOTE4" }, + { "id": "MDQ6VXNlcjE5ODIxMTcx" }, + { "id": "MDQ6VXNlcjIxMTI5NjM5" }, + { "id": "MDQ6VXNlcjI1NDA0Nzgz" }, + { "id": "MDQ6VXNlcjM4OTYyMjQz" }, + { "id": "MDQ6VXNlcjQ2NjEyOTMz" }, + { "id": "MDQ6VXNlcjY4NDAzMzQw" }, + { "id": "U_kgDOBef8kg" }, + { "id": "U_kgDOBewVSw" }, + { "id": "U_kgDOCR6ywQ" } + ] + } + }, { "name": "Hacky Hour", "members": { "nodes": [ - { "id": "cat" }, - { "id": "mouse" }, - { "id": "squirrel" } + { "id": "MDQ6VXNlcjc0MjYzMw==" }, + { "id": "MDQ6VXNlcjY5NDcwODk=" }, + { "id": "MDQ6VXNlcjEyNjkxOTE4" } ] } }, { "name": "Coffee and Code", "members": { - "nodes": [{ "id": "dog" }, { "id": "cat" }] + "nodes": [ + { "id": "MDQ6VXNlcjc0MjYzMw==" }, + { "id": "U_kgDOBef8kg" } + ] } } ] @@ -24,39 +76,435 @@ "membersWithRole": { "nodes": [ { - "id": "dog", - "name": "Dog", - "login": "dog", - "bio": "The best dog ever", - "company": "Pets, Inc.", - "avatarUrl": "https://picsum.photos/id/237/200", + "id": "MDQ6VXNlcjc0MjYzMw==", + "name": "Julian Pistorius", + "login": "julianpistorius", + "bio": "Organic Software Gardener 🍅", + "company": "Exosphere Project", + "avatarUrl": "https://avatars.githubusercontent.com/u/742633?u=204cc5138bfb07ef7332d3fa1d885bbbbe9e7281&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjEyMTU4NzM=", + "name": "Alex Bigelow", + "login": "alex-r-bigelow", + "bio": "I research how (and build software for!) people as they think about, reshape, and visualize data", + "company": "Stardog", + "avatarUrl": "https://avatars.githubusercontent.com/u/1215873?u=9a4a9336866c4a348a0bb220a6e0490963bf32b5&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "LINKEDIN", + "url": "https://www.linkedin.com/in/alex-bigelow-65145259/" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjE5Mzk4MTM=", + "name": "Jeff Oliver", + "login": "jcoliver", + "bio": "", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/1939813?u=d39a4cac18c94ef60a298c2ad5fa82bb73fc30c3&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/jcoliverAZ" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjM4ODMyNDE=", + "name": "Soham Pal", + "login": "e-eight", + "bio": "Computing Sciences Researcher II at The University of Arizona.", + "company": "The University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/3883241?u=bb818aa9153eb92f57ae7b878a39faed4988f025&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/dragonbornmonk" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjY2MTczMzI=", + "name": "Meghan Balk", + "login": "megbalk", + "bio": "", + "company": "Natural History Museum, University of Oslo", + "avatarUrl": "https://avatars.githubusercontent.com/u/6617332?u=3836c3ffa014b36b188f4f45297f26461fb39a67&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjY5NDcwODk=", + "name": "Ryan Bartelme", + "login": "rbartelme", + "bio": "Staff Data Scientist in biotechnology research and development", + "company": "Accelerate Diagnostics", + "avatarUrl": "https://avatars.githubusercontent.com/u/6947089?u=9cc0c86dc9db92eb4358b6b9643b79db33b279f2&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/MicrobialBart" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjcwODIwMjU=", + "name": "Fernando Rios", + "login": "zoidy", + "bio": "-_-", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/7082025?v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "MASTODON", + "url": "https://fosstodon.org/@riosfrnd" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjEwMzM1NDc5", + "name": "Adriana Picoral", + "login": "picoral", + "bio": "", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/10335479?u=b9414a8cb122c29d6c8544baea85a84c6baab939&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/adrianapicoral" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjExMDIzMzE3", + "name": "Blake Joyce", + "login": "bjoyce3", + "bio": "I'm a code curious biologist.", + "company": "University of Alabama at Birmingham", + "avatarUrl": "https://avatars.githubusercontent.com/u/11023317?u=7200ca4bee6441f2ef582f70df5fe39bd236e3ee&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjExNTI3MDQx", + "name": "Tyson L. Swetnam", + "login": "tyson-swetnam", + "bio": "Director of Open Science & Associate Professor at the University of Arizona, Institute for Computation and Data Enabled Insight ", + "company": "University of Arizona, CyVerse", + "avatarUrl": "https://avatars.githubusercontent.com/u/11527041?u=2cefefd17d2dc2ec8243b7a1f53a620f1fde2ff4&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/tswetnam" + } + }, + { + "node": { + "provider": "LINKEDIN", + "url": "https://www.linkedin.com/in/tyson-swetnam/" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjEyMDIyMDc2", + "name": "Jessica Guo", + "login": "jessicaguo", + "bio": "", + "company": "University of Arizona, CCT Data Science", + "avatarUrl": "https://avatars.githubusercontent.com/u/12022076?u=377f60f40b83a81b1e57ef8518406bc38ce6748f&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/JessicaSGuo" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjEyNjkxOTE4", + "name": "Brandon Jernigan", + "login": "brandon-jernigan", + "bio": null, + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/12691918?u=a1c7d45e5755e99746ae358919406cc7f163b192&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjE5ODIxMTcx", + "name": "Laura W. Dozal", + "login": "lwdozal", + "bio": "PhD Student at the University of Arizona's School of Information", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/19821171?u=3cca330b757c209c3c1547844a3ad81508304b58&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjIwMzA1NzM0", + "name": "Chun Ly", + "login": "astrochun", + "bio": "Staring at the universe's data in the dark.", + "company": "Princeton Plasma Physics Lab; Steward Obs", + "avatarUrl": "https://avatars.githubusercontent.com/u/20305734?u=84a111e22eef413d58e1370acea7cb12d075fc05&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/astrochunly" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjIxMTI5NjM5", + "name": "Heidi Steiner", + "login": "hidyverse", + "bio": "", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/21129639?u=f02dbb9a9ecfad325fa0ead8378f8d77f9150012&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjIyMzgxNTM2", + "name": null, + "login": "chrisreidy", + "bio": "", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/22381536?u=5925008755e77dd5f884bd288ed6c0ff6f29a25d&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjI1MjM1MjI4", + "name": "Jennifer Nichols", + "login": "jennytnichols", + "bio": "Librarian @ University of Arizona\r\nDirector, Catalyst Studios\r\n@resbazaz organizer\r\n", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/25235228?u=84becdeac90a0ca8727cfcbfac7988ba13baca46&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjI1NDA0Nzgz", + "name": "Eric R. Scott", + "login": "Aariq", + "bio": "Scientific Programmer & Educator at University of Arizona", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/25404783?u=bf39b8163e91fb40423676c1806a9fc1ed665c0c&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/leafyericscott" + } + }, + { + "node": { + "provider": "MASTODON", + "url": "https://fosstodon.org/@LeafyEricScott" + } + }, + { + "node": { + "provider": "LINKEDIN", + "url": "https://www.linkedin.com/in/eric-r-scott-phd/" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjM0NDY2OTQx", + "name": "Sarah Stueve", + "login": "sarahstueve", + "bio": "", + "company": "University of Arizona's iSchool", + "avatarUrl": "https://avatars.githubusercontent.com/u/34466941?u=c00f55a3718179e6d8e73acf75d18f3373a59da9&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjM0NDg2MTU0", + "name": null, + "login": "MagicMilly", + "bio": "Turkeys make excellent companions.", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/34486154?v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjM2MTczNDkw", + "name": "Joanne B", + "login": "jberghout", + "bio": "Computational geneticist", + "company": "NIH", + "avatarUrl": "https://avatars.githubusercontent.com/u/36173490?v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/joanneberghout" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjM4OTYyMjQz", + "name": "Greg T. Chism", + "login": "Gchism94", + "bio": "Data Scientist | PhD, University of Arizona | R/RStudio Evangelist", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/38962243?u=7ec452e5b8489ddbd966d22fdd5984332225c2ad&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjQxNzA2OTE1", + "name": "Rebecca Vanderpool", + "login": "vanderpoolrr", + "bio": "", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/41706915?u=f94237b4dc3896de97d3fd66872ac172fb638337&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjQ2NjEyOTMz", + "name": "Miriam Keppler", + "login": "kepplerm", + "bio": "Astronomer, Data Scientist, Space Science & EO Enthusiast", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/46612933?v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjQ3NzY2MDc0", + "name": "Drake Asberry", + "login": "drakeasberry", + "bio": "", + "company": "GSA", + "avatarUrl": "https://avatars.githubusercontent.com/u/47766074?u=6e52d4344ed85cd5c8b5e873ec28f1d5e74907e9&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjU2NzAyNjAw", + "name": "Lia Ossanna", + "login": "lossanna", + "bio": "", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/56702600?u=03ece3573c51cb41e21197f7c2071d122d5e25a8&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/LiaOssanna" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjYxMzI5OTE2", + "name": null, + "login": "rbelshe", + "bio": null, + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/61329916?v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "MDQ6VXNlcjY4NDAzMzQw", + "name": "Emma Reich", + "login": "egreich", + "bio": "PhD Student in Ecological and Environmental Informatics,\r\nSchool of Informatics, Computing, and Cyber Systems\r\n \r\n\r\n", + "company": "Northern Arizona University", + "avatarUrl": "https://avatars.githubusercontent.com/u/68403340?u=d3e846be891006b37a7aae3b74c7ecde9d0ab6fd&v=4", + "socialAccounts": { + "edges": [ + { + "node": { + "provider": "TWITTER", + "url": "https://twitter.com/ecophys_emma" + } + } + ] + } + }, + { + "id": "MDQ6VXNlcjcyOTQwMjg2", + "name": null, + "login": "karendelarosa", + "bio": null, + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/72940286?u=c0d118c3c830aa038eb2993753b42979431b3dd2&v=4", + "socialAccounts": { "edges": [] } + }, + { + "id": "U_kgDOBdICzA", + "name": "Laura Palacios Falk", + "login": "LauraFalk", + "bio": "", + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/97649356?v=4", "socialAccounts": { "edges": [] } }, { - "id": "cat", - "name": "Cat", - "login": "cat", - "bio": "wut", - "company": "Pets, Inc.", - "avatarUrl": "https://picsum.photos/id/238/200", + "id": "U_kgDOBef8kg", + "name": null, + "login": "val-pf", + "bio": "", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/99089554?u=1441d55ea7637555aca31523963c26a68df6f57f&v=4", "socialAccounts": { "edges": [] } }, { - "id": "mouse", - "name": "Mouse", - "login": "mouse", - "bio": "i heart cheese", - "company": "roDENTS", - "avatarUrl": "https://picsum.photos/id/239/200", + "id": "U_kgDOBewVSw", + "name": null, + "login": "TinaJAZ", + "bio": null, + "company": null, + "avatarUrl": "https://avatars.githubusercontent.com/u/99358027?v=4", "socialAccounts": { "edges": [] } }, { - "id": "squirrel", - "name": "Squirrel", - "login": "squirrel", - "bio": "you'll never find my acorns", - "company": "roDENTS", - "avatarUrl": "https://picsum.photos/id/240/200", + "id": "U_kgDOCR6ywQ", + "name": "Ethan Jahn", + "login": "ejahnUA", + "bio": "", + "company": "University of Arizona", + "avatarUrl": "https://avatars.githubusercontent.com/u/153006785?u=d14316c1567ab29135738cc82d41d37607b9963f&v=4", "socialAccounts": { "edges": [] } } ] diff --git a/data/toyPeople.json b/data/toyPeople.json new file mode 100644 index 0000000..4ada482 --- /dev/null +++ b/data/toyPeople.json @@ -0,0 +1,66 @@ +{ + "data": { + "organization": { + "teams": { + "nodes": [ + { + "name": "Hacky Hour", + "members": { + "nodes": [ + { "id": "cat" }, + { "id": "mouse" }, + { "id": "squirrel" } + ] + } + }, + { + "name": "Coffee and Code", + "members": { + "nodes": [{ "id": "dog" }, { "id": "cat" }] + } + } + ] + }, + "membersWithRole": { + "nodes": [ + { + "id": "dog", + "name": "Dog", + "login": "dog", + "bio": "The best dog ever", + "company": "Pets, Inc.", + "avatarUrl": "https://picsum.photos/id/237/200", + "socialAccounts": { "edges": [] } + }, + { + "id": "cat", + "name": "Cat", + "login": "cat", + "bio": "wut", + "company": "Pets, Inc.", + "avatarUrl": "https://picsum.photos/id/238/200", + "socialAccounts": { "edges": [] } + }, + { + "id": "mouse", + "name": "Mouse", + "login": "mouse", + "bio": "i heart cheese", + "company": "roDENTS", + "avatarUrl": "https://picsum.photos/id/239/200", + "socialAccounts": { "edges": [] } + }, + { + "id": "squirrel", + "name": "Squirrel", + "login": "squirrel", + "bio": "you'll never find my acorns", + "company": "roDENTS", + "avatarUrl": "https://picsum.photos/id/240/200", + "socialAccounts": { "edges": [] } + } + ] + } + } + } +} diff --git a/theme.scss b/theme.scss index a6f5754..e9d9c42 100644 --- a/theme.scss +++ b/theme.scss @@ -18,7 +18,7 @@ $gray-800: #333 !default; $gray-900: #212529 !default; $black: #000 !default; -$blue: #007bff !default; +$blue: #1e58ac !default; $indigo: #6610f2 !default; $purple: #772953 !default; $pink: #e83e8c !default; diff --git a/whoWeAre.qmd b/whoWeAre.qmd index 328fc18..729fe29 100644 --- a/whoWeAre.qmd +++ b/whoWeAre.qmd @@ -1,5 +1,23 @@ --- title: "Who We Are" +page-layout: full +execute: + echo: false --- -TODO \ No newline at end of file +We're a community of current / former / aspirational researchers, data scientists, and friends helping each other to learn new technologies via various different events. + +This is a diagram of who is involved in our weekly meetups, and who has has put in the work to organize our bigger festival events. + +TODO: + +- Click nodes to learn more! + - Highlight clicked nodes, show selected event / github profile links +- Add a bounding box force, use space more effectively +- Prettier links, fonts + +```{ojs} +import { nodeLinkDiagram } from './components/nodeLinkDiagram.ojs'; + +nodeLinkDiagram(); +``` \ No newline at end of file From 45c135af6c6873894b01e8404e6dba72eb25663b Mon Sep 17 00:00:00 2001 From: Alex Bigelow Date: Wed, 20 Mar 2024 15:24:58 -0700 Subject: [PATCH 2/5] Make nodes selectable, add boundary / gravity forces --- components/nodeLinkDiagram.ojs | 275 ++++++++++++++++++++++----------- whoWeAre.qmd | 66 ++++++-- 2 files changed, 242 insertions(+), 99 deletions(-) diff --git a/components/nodeLinkDiagram.ojs b/components/nodeLinkDiagram.ojs index 0fc0936..987e34a 100644 --- a/components/nodeLinkDiagram.ojs +++ b/components/nodeLinkDiagram.ojs @@ -1,13 +1,24 @@ people = FileAttachment("data/people.json").json(); -function nodeLinkDiagram () { - const height = width * 0.6; +nodeLinkDiagram = { + let selectNode, selectedNode = null; + + const height = globalThis.screen.height - 200; const personNodeRadius = 25; + const personNodePaddedRadius = personNodeRadius + 15; + + const highlightOutlineRadius = 5; + const highlightStrokeWeight = 5; const teamNodeRadius = 75; - const strokeWeight = 5; + const strokeWeight = 3; + + const gravityMultiplier = 0.3; + const maxGravityAlpha = 0.0005; + const bounceStrength = 2; + const chargeStrength = -2000; // -10 * (personNodeRadius + teamNodeRadius); const weeklyTeams = new Set([ 'coffee_and_code', @@ -43,118 +54,204 @@ function nodeLinkDiagram () { ) .force( "charge", - d3.forceManyBody().strength(-30 * (personNodeRadius + teamNodeRadius)) + d3.forceManyBody().strength(chargeStrength) ) - .force("center", d3.forceCenter(width / 2, height / 2)); + .force("centerAndBounds", (alpha) => { + nodes.forEach(d => { + const radius = d.type === 'PERSON' ? personNodePaddedRadius : teamNodeRadius; + // Kinda weird, but has a nice effect: apply gravity more strongly + // (within a limit) at the beginning of a layout / while you're + // dragging, but taper it off toward the end + const gravityAlpha = Math.min((alpha * gravityMultiplier) ** 2, maxGravityAlpha); - const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]); + if (d.x < radius) { + d.x = radius; + d.vx += alpha * bounceStrength * (radius - d.x); + } else if (d.x > width - radius) { + d.x = width - radius; + d.vx += -alpha * bounceStrength * (d.x - width - radius); + } + const dx = width / 2 - d.x; + d.vx += Math.sign(dx) * gravityAlpha * dx ** 2; + + if (d.y < radius) { + d.y = radius; + d.vy += alpha * bounceStrength * (radius - d.y); + } else if (d.y > height - radius) { + d.y = height - radius; + d.vy += -alpha * bounceStrength * (d.y - height - radius); + } + const dy = height / 2 - d.y; + d.vy += Math.sign(dy) * gravityAlpha * dy ** 2; + }); + }) + .force('collide', d3.forceCollide((d) => d.type === 'PERSON' ? personNodePaddedRadius : teamNodeRadius)); + + const svg = d3.create("svg") + .attr("viewBox", [0, 0, width, height]) + .style("user-select", "none"); + svg.append('g') + .classed('links', true); + svg.append('g') + .classed('nodes', true); let draggedNode = null; - let selectedNode = null; + let dragOffset = null; - function mousedown(_, node) { + function mousedown(event, node) { if (draggedNode) { return; } - simulation.alphaTarget(0.3).restart(); - draggedNode = selectedNode = node.id; - node.fx = node.x; - node.fy = node.y; + const bounds = svg.node().getBoundingClientRect(); + simulation.alphaTarget(0.025).restart(); + draggedNode = node; + selectNode(draggedNode); + const clickedPoint = { + x: event.x - bounds.left, + y: event.y - bounds.top + }; + dragOffset = { + dx: clickedPoint.x - draggedNode.x, + dy: clickedPoint.y - draggedNode.y + }; + // console.log('down', event, bounds, draggedNode, clickedPoint, dragOffset); + draggedNode.fx = draggedNode.x; + draggedNode.fy = draggedNode.y; } - function mousemove(event, node) { + function mousemove(event) { if (!draggedNode) { return; } const bounds = svg.node().getBoundingClientRect(); - node.fx = event.x - bounds.left; - node.fy = event.y - bounds.top; + const clickedPoint = { + x: event.x - bounds.left, + y: event.y - bounds.top + }; + // console.log('move', event, bounds, clickedPoint, dragOffset); + draggedNode.fx = clickedPoint.x - dragOffset.dx; + draggedNode.fy = clickedPoint.y - dragOffset.dy; } - function mouseup(_, event) { + function mouseup(event) { if (!draggedNode) { return; } + // console.log('up', draggedNode, dragOffset); + draggedNode.fx = null; + draggedNode.fy = null; draggedNode = null; + dragOffset = null; simulation.alphaTarget(0); - node.fx = null; - node.fy = null; } - const link = svg - .append("g") - .attr("stroke", "#999") - .attr("stroke-opacity", 0.6) - .selectAll("line") - .data(links) - .join("line") - .attr("stroke-width", strokeWeight); - - const node = svg - .append("g") - .selectAll("g.node") - .data(nodes) - .join("g") - .classed("node", true) - // d3.drag() does weird things with quarto's minified version of d3... - // plus, this lets us control clicking vs dragging ourselves - .on('mousedown', mousedown) - .on('mousemove', mousemove) - .on('mouseup', mouseup); - - const teamCircle = node - .filter((d) => d.type !== "PERSON") - .append("circle") - .attr("r", teamNodeRadius) - .style("fill", d => teamColors(d.type)); - - const clipPath = node - .filter((d) => d.type === "PERSON") - .append("clipPath") - .attr("id", (d) => d.id) - .append("circle") - .attr("id", (d) => d.id) - .attr("r", personNodeRadius); - - // Append images - const profileImage = node - .filter((d) => d.type === "PERSON") - .append("image") - .attr("href", (d) => d.avatarUrl) - .attr("x", (d) => -personNodeRadius) - .attr("y", (d) => -personNodeRadius) - .attr("width", personNodeRadius * 2) - .attr("height", personNodeRadius * 2) - .attr("clip-path", (d) => `url(#${d.id})`) - .attr("preserveAspectRatio", "xMidYMin slice"); - - const text = node - .append("text") - .attr("class", "node_label") - .attr("y", (d) => - d.type === "PERSON" ? `${personNodeRadius}px` : "0.5em" - ) - .style("fill", (d) => (d.type === "PERSON" ? "black" : "white")) - .style("dominant-baseline", (d) => - d.type === "PERSON" ? "hanging" : "bottom" - ) - .style("text-anchor", "middle") - .style("font-size", "10pt") - .text((d) => d.name); + function * render (_selectNode, _selectedNode) { + selectNode = _selectNode; + selectedNode = _selectedNode; - node.append("title").text((d) => d.id); + let link = svg + .select(".links") + .selectAll("line") + .data(links, (d) => `${d.from?.id}_${d.to?.id}`); + const linkEnter = link.enter() + .append("line") + .attr("stroke", "#999") + .attr("stroke-opacity", 0.6) + .attr("stroke-width", strokeWeight); + link.exit().remove(); + link = link.merge(linkEnter); - simulation.on("tick", () => { - link - .attr("x1", (d) => d.source.x) - .attr("y1", (d) => d.source.y) - .attr("x2", (d) => d.target.x) - .attr("y2", (d) => d.target.y); + let node = svg + .select(".nodes") + .selectAll("g.node") + .data(nodes, (d) => d.id); + const nodeEnter = node.enter() + .append('g') + .classed('node', true); + node.exit().remove(); + node = node.merge(nodeEnter) + // d3.drag() does weird things with quarto's minified version of d3, and + // isn't very retina display-friendly... so we manage interactions ourselves + .on('mousedown', mousedown); + d3.select(document) + .on('mousemove', mousemove) + .on('mouseup', mouseup); + + nodeEnter + .append("circle") + .classed('outline', true) + .attr("r", (d) => highlightOutlineRadius + (d.type === "PERSON" ? personNodeRadius : teamNodeRadius)) + .style('fill', 'none') + .style('stroke', '#333') + .style('stroke-width', highlightStrokeWeight); + node.select('.outline') + .style('display', d => d.id === selectedNode?.id ? null : 'none'); - node.attr("transform", (d) => "translate(" + d.x + "," + d.y + ")"); - }); + nodeEnter + .filter((d) => d.type !== "PERSON") + .append("circle") + .attr("r", teamNodeRadius) + .style("fill", d => teamColors(d.type)); + + nodeEnter + .filter((d) => d.type === "PERSON") + .append("clipPath") + .attr("id", (d) => d.id) + .append("circle") + .attr("id", (d) => d.id) + .attr("r", personNodeRadius); - // invalidation.then(() => simulation.stop()); + nodeEnter + .filter((d) => d.type === "PERSON") + .append("image") + .attr("href", (d) => d.avatarUrl) + .attr("x", (d) => -personNodeRadius) + .attr("y", (d) => -personNodeRadius) + .attr("width", personNodeRadius * 2) + .attr("height", personNodeRadius * 2) + .attr("clip-path", (d) => `url(#${d.id})`) + .attr("preserveAspectRatio", "xMidYMin slice"); + + nodeEnter + .append("text") + .attr("class", "node_label") + .style("fill", (d) => (d.type === "PERSON" ? "black" : "white")) + .style("dominant-baseline", (d) => + d.type === "PERSON" ? "hanging" : "bottom" + ) + .style("text-anchor", "middle") + .style("font-size", "10pt") + .text((d) => d.name || d.login); + node.select('text') + .attr("y", (d) => { + if (d.type !== 'PERSON') { + return "0.5em"; + } + if (d.id === selectedNode?.id) { + return `${personNodeRadius + 2 * highlightOutlineRadius}px`; + } + return `${personNodeRadius}px`; + }); + + nodeEnter + .append("title") + .text((d) => d.name || d.login); + + simulation.on("tick", () => { + node + .attr("transform", (d) => "translate(" + d.x + "," + d.y + ")"); + + link + .attr("x1", (d) => d.source.x) + .attr("y1", (d) => d.source.y) + .attr("x2", (d) => d.target.x) + .attr("y2", (d) => d.target.y); + }); + + invalidation.then(() => simulation.stop()); + + yield svg.node(); + } - return svg.node(); + return render; } \ No newline at end of file diff --git a/whoWeAre.qmd b/whoWeAre.qmd index 729fe29..d35283c 100644 --- a/whoWeAre.qmd +++ b/whoWeAre.qmd @@ -1,10 +1,63 @@ --- -title: "Who We Are" -page-layout: full +layout: default execute: echo: false --- +```{ojs} +import { nodeLinkDiagram } from './components/nodeLinkDiagram.ojs'; + +mutable selectedNode = null +``` + +::: { .column-screen-left } +```{ojs} +graph = nodeLinkDiagram((node) => { + mutable selectedNode = node; +}, selectedNode); +``` +::: + +::: { .column-margin } +```{ojs} +{ + if (selectedNode === null) { + return md` +*Click a node for more information* + `; + } else if (selectedNode.type === 'PERSON') { + const header = selectedNode.name + ? md`# ${selectedNode.name}` + : (selectedNode.login + ? md`# ${selectedNode.login}` + : ''); + + const profilePic = selectedNode.avatarUrl ? html`
+ +
` : ''; + + const company = selectedNode.company ? md`*${selectedNode.company}*` : ''; + + // TODO: selectedNode.login for github link / icon, selectedNode.socialAccounts list for others + + const bio = selectedNode.bio ? md`${selectedNode.bio}` : ''; + + return md` +${header} +${profilePic} +${company} +${bio} +`; + } + // TODO: sidebar for selectedNode.type === 'WEEKLY' + // TODO: sidebar for selectedNode.type === 'FESTIVAL' + return html`

Error! Unknown node:

${
+    JSON.stringify(selectedNode, null, 2)
+  }

`; +} +``` +::: + We're a community of current / former / aspirational researchers, data scientists, and friends helping each other to learn new technologies via various different events. This is a diagram of who is involved in our weekly meetups, and who has has put in the work to organize our bigger festival events. @@ -13,11 +66,4 @@ TODO: - Click nodes to learn more! - Highlight clicked nodes, show selected event / github profile links -- Add a bounding box force, use space more effectively -- Prettier links, fonts - -```{ojs} -import { nodeLinkDiagram } from './components/nodeLinkDiagram.ojs'; - -nodeLinkDiagram(); -``` \ No newline at end of file +- Prettier links, fonts \ No newline at end of file From f667a4fa7d438d21603914ff25064612a756d2e2 Mon Sep 17 00:00:00 2001 From: Alex Bigelow Date: Fri, 29 Mar 2024 17:30:14 -0700 Subject: [PATCH 3/5] Slightly better height --- components/nodeLinkDiagram.ojs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/nodeLinkDiagram.ojs b/components/nodeLinkDiagram.ojs index 987e34a..d546d7e 100644 --- a/components/nodeLinkDiagram.ojs +++ b/components/nodeLinkDiagram.ojs @@ -3,7 +3,7 @@ people = FileAttachment("data/people.json").json(); nodeLinkDiagram = { let selectNode, selectedNode = null; - const height = globalThis.screen.height - 200; + const height = globalThis.screen.height; const personNodeRadius = 25; const personNodePaddedRadius = personNodeRadius + 15; From c89f44efc5fae0d5a08479507d36369e7556e7ad Mon Sep 17 00:00:00 2001 From: Alex Bigelow Date: Fri, 5 Apr 2024 14:58:12 -0700 Subject: [PATCH 4/5] Support adding / overriding with custom data --- .github/workflows/build.yml | 1 + components/nodeLinkDiagram.ojs | 32 +--- components/randomAvatars.ojs | 25 ++- components/utilities.ojs | 81 ++++++++++ data/overrides.json | 22 +++ data/people.json | 288 ++++++++++++++++++++++++++------- img/logos/facebook.svg | 44 +++++ img/logos/github.svg | 57 +++++++ img/logos/instagram.svg | 101 ++++++++++++ img/logos/link.svg | 70 ++++++++ img/logos/linkedin.svg | 54 +++++++ img/logos/mastodon.svg | 47 ++++++ img/logos/pinterest.svg | 45 ++++++ img/logos/reddit.svg | 49 ++++++ img/logos/twitter.svg | 58 +++++++ index.qmd | 9 +- styles/whoWeAre.css | 8 + whoWeAre.qmd | 60 +++++-- 18 files changed, 925 insertions(+), 126 deletions(-) create mode 100644 components/utilities.ojs create mode 100644 data/overrides.json create mode 100644 img/logos/facebook.svg create mode 100644 img/logos/github.svg create mode 100644 img/logos/instagram.svg create mode 100644 img/logos/link.svg create mode 100644 img/logos/linkedin.svg create mode 100644 img/logos/mastodon.svg create mode 100644 img/logos/pinterest.svg create mode 100644 img/logos/reddit.svg create mode 100644 img/logos/twitter.svg create mode 100644 styles/whoWeAre.css diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0ca3cf7..ec3beaa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,6 +33,7 @@ jobs: bio company avatarUrl + websiteUrl socialAccounts(first:10) { edges { node { diff --git a/components/nodeLinkDiagram.ojs b/components/nodeLinkDiagram.ojs index 5fdcd64..b431117 100644 --- a/components/nodeLinkDiagram.ojs +++ b/components/nodeLinkDiagram.ojs @@ -1,6 +1,4 @@ -people = FileAttachment("data/people.json").json(); - -function nodeLinkDiagram() { +function nodeLinkDiagram(nodes, links) { let selectNode, selectedNode = null; @@ -21,36 +19,11 @@ function nodeLinkDiagram() { const bounceStrength = 2; const chargeStrength = -2000; // -10 * (personNodeRadius + teamNodeRadius); - const weeklyTeams = new Set(["coffee_and_code", "hacky_hour"]); - const teamColors = d3.scaleOrdinal( ["WEEKLY", "FESTIVAL"], ["#ea5a2a", "#1e58ac"] ); - const peopleById = Object.fromEntries( - people.data.organization.membersWithRole.nodes.map((person) => [ - person.id, - { - ...person, - type: "PERSON", - }, - ]) - ); - const nodes = Object.values(peopleById); - const links = []; - people.data.organization.teams.nodes.forEach((team) => { - const teamId = team.name.toLowerCase().replace(/\s+/g, "_"); - nodes.push({ - id: teamId, - name: team.name, - type: weeklyTeams.has(teamId) ? "WEEKLY" : "FESTIVAL", - }); - team.members.nodes.forEach((member) => { - links.push({ source: member.id, target: teamId }); - }); - }); - const simulation = d3 .forceSimulation(nodes) .force( @@ -124,7 +97,6 @@ function nodeLinkDiagram() { dx: clickedPoint.x - draggedNode.x, dy: clickedPoint.y - draggedNode.y, }; - // console.log('down', event, bounds, draggedNode, clickedPoint, dragOffset); draggedNode.fx = draggedNode.x; draggedNode.fy = draggedNode.y; } @@ -138,7 +110,6 @@ function nodeLinkDiagram() { x: event.x - bounds.left, y: event.y - bounds.top, }; - // console.log('move', event, bounds, clickedPoint, dragOffset); draggedNode.fx = clickedPoint.x - dragOffset.dx; draggedNode.fy = clickedPoint.y - dragOffset.dy; } @@ -147,7 +118,6 @@ function nodeLinkDiagram() { if (!draggedNode) { return; } - // console.log('up', draggedNode, dragOffset); draggedNode.fx = null; draggedNode.fy = null; draggedNode = null; diff --git a/components/randomAvatars.ojs b/components/randomAvatars.ojs index e40344d..f25dc48 100644 --- a/components/randomAvatars.ojs +++ b/components/randomAvatars.ojs @@ -1,33 +1,28 @@ -peopleFile = FileAttachment("data/people.json").json(); - /** * An observable.js widget that shows profile pictures for ResBaz GitHub Team * members; see index.qmd for examples. Additionally, some relevant styles are * in styles/index.css * + * @param peopleData The results of combineAndOverrideGithubData() * @param teamName A string that should correspond to the name of an entry in - * data/people.json, under data.organization.teams.nodes + * data/people.json under data.organization.teams.nodes, + * or a key under teams in data/overrides.json, * @returns A DOM element that can be embedded via an ojs cell */ -function randomAvatars(teamName) { - const team = peopleFile.data.organization.teams.nodes.find( - (team) => team.name === teamName - ); - const people = team.members.nodes - .map(({ id }) => - peopleFile.data.organization.membersWithRole.nodes.find( - (person) => person.id === id - ) - ) +function randomAvatars(peopleData, teamId) { + const team = peopleData.teamsById[teamId]; + const people = team.members + .map((id) => peopleData.peopleById[id]) .sort(() => 2 * Math.random() - 1); const container = d3.create("div").classed("randomAvatars", true); container - .selectAll("img") + .selectAll("a") .data(people) .enter() + .append("a") + .attr("href", (person) => `./whoWeAre.html#${person.hash}`) .append("img") .attr("src", (person) => person.avatarUrl) .attr("title", (person) => person.name); - // TODO: link to the Who We Are page, when a profile picture is clicked return container.node(); } diff --git a/components/utilities.ojs b/components/utilities.ojs new file mode 100644 index 0000000..a26a3c0 --- /dev/null +++ b/components/utilities.ojs @@ -0,0 +1,81 @@ +people = FileAttachment("data/people.json").json(); +overrides = FileAttachment("data/overrides.json").json(); + +function combineAndOverrideGithubData() { + const peopleById = { + // Include people manually added in overrides.json, that may not have a + // github login (or their info hasn't been queried yet by + // .github/workflows/build.yml, e.g. during local development) + ...overrides.people, + ...Object.fromEntries( + people.data.organization.membersWithRole.nodes.map((person) => [ + person.login, + { + ...person, + // Github stores people by an illegible hash; we want to select + + // override data using Github usernames as ids (but still use + // hashes for url navigation) + hash: person.id, + id: person.login, + type: "PERSON", + // Override github profile information with details in overrides.json + ...(overrides.people[person?.login] || {}), + }, + ]) + ), + }; + + const peopleByHash = Object.fromEntries( + Object.values(peopleById).map((person) => [person.hash, person]) + ); + + const teamsById = { + // Include this separately for manual "teams" that aren't on Github + ...overrides.teams, + ...Object.fromEntries( + people.data.organization.teams.nodes.map((team) => { + const teamId = team.name.toLowerCase().replace(/\s+/g, "_"); + return [ + teamId, + { + id: teamId, + name: team.name, + type: "FESTIVAL", // For non-festival "teams," add an override! + members: team.members.nodes.map(({ id }) => peopleByHash[id].login), + // Override any github teams with details in overrides.json + ...(overrides.teams[teamId] || {}), + }, + ]; + }) + ), + }; + Object.entries(teamsById).forEach(([teamId, team]) => { + // Some extra fields that we don't want to have to hand-code + // in overrides.json + if (!team.hash) { + team.id = teamId; + team.hash = teamId; + } + if (!team.type) { + team.type = "FESTIVAL"; + } + }); + + const nodes = [...Object.values(peopleById), ...Object.values(teamsById)]; + const links = []; + Object.values(teamsById).forEach((team) => { + team.members.forEach((member) => { + links.push({ source: member, target: team.id }); + }); + }); + + return { + peopleById, + peopleByHash, + teamsById, + graph: { + nodes, + links, + }, + }; +} diff --git a/data/overrides.json b/data/overrides.json new file mode 100644 index 0000000..13d5699 --- /dev/null +++ b/data/overrides.json @@ -0,0 +1,22 @@ +{ + "teams": { + "festival2024": { + "name": "2024 Festival Organizers" + }, + "TestTeam": { + "name": "Test Team", + "members": ["alex-r-bigelow"] + }, + "coffee_and_code": { + "type": "WEEKLY" + }, + "hacky_hour": { + "type": "WEEKLY" + } + }, + "people": { + "alex-r-bigelow": { + "bio": "I research how (and build software for!) people as they think about, reshape, and visualize data" + } + } +} diff --git a/data/people.json b/data/people.json index 6464aaa..74a463b 100644 --- a/data/people.json +++ b/data/people.json @@ -7,15 +7,33 @@ "name": "Website Team", "members": { "nodes": [ - { "id": "MDQ6VXNlcjc0MjYzMw==" }, - { "id": "MDQ6VXNlcjEyMTU4NzM=" }, - { "id": "MDQ6VXNlcjE5Mzk4MTM=" }, - { "id": "MDQ6VXNlcjcwODIwMjU=" }, - { "id": "MDQ6VXNlcjExMDIzMzE3" }, - { "id": "MDQ6VXNlcjEyMDIyMDc2" }, - { "id": "MDQ6VXNlcjIxMTI5NjM5" }, - { "id": "MDQ6VXNlcjM4OTYyMjQz" }, - { "id": "U_kgDOBef8kg" } + { + "id": "MDQ6VXNlcjc0MjYzMw==" + }, + { + "id": "MDQ6VXNlcjEyMTU4NzM=" + }, + { + "id": "MDQ6VXNlcjE5Mzk4MTM=" + }, + { + "id": "MDQ6VXNlcjcwODIwMjU=" + }, + { + "id": "MDQ6VXNlcjExMDIzMzE3" + }, + { + "id": "MDQ6VXNlcjEyMDIyMDc2" + }, + { + "id": "MDQ6VXNlcjIxMTI5NjM5" + }, + { + "id": "MDQ6VXNlcjM4OTYyMjQz" + }, + { + "id": "U_kgDOBef8kg" + } ] } }, @@ -23,11 +41,21 @@ "name": "Governance Task Force", "members": { "nodes": [ - { "id": "MDQ6VXNlcjc0MjYzMw==" }, - { "id": "MDQ6VXNlcjEyMTU4NzM=" }, - { "id": "MDQ6VXNlcjIxMTI5NjM5" }, - { "id": "MDQ6VXNlcjU2NzAyNjAw" }, - { "id": "U_kgDOBef8kg" } + { + "id": "MDQ6VXNlcjc0MjYzMw==" + }, + { + "id": "MDQ6VXNlcjEyMTU4NzM=" + }, + { + "id": "MDQ6VXNlcjIxMTI5NjM5" + }, + { + "id": "MDQ6VXNlcjU2NzAyNjAw" + }, + { + "id": "U_kgDOBef8kg" + } ] } }, @@ -35,20 +63,48 @@ "name": "Festival2024", "members": { "nodes": [ - { "id": "MDQ6VXNlcjc0MjYzMw==" }, - { "id": "MDQ6VXNlcjEyMTU4NzM=" }, - { "id": "MDQ6VXNlcjE5Mzk4MTM=" }, - { "id": "MDQ6VXNlcjM4ODMyNDE=" }, - { "id": "MDQ6VXNlcjEyNjkxOTE4" }, - { "id": "MDQ6VXNlcjE5ODIxMTcx" }, - { "id": "MDQ6VXNlcjIxMTI5NjM5" }, - { "id": "MDQ6VXNlcjI1NDA0Nzgz" }, - { "id": "MDQ6VXNlcjM4OTYyMjQz" }, - { "id": "MDQ6VXNlcjQ2NjEyOTMz" }, - { "id": "MDQ6VXNlcjY4NDAzMzQw" }, - { "id": "U_kgDOBef8kg" }, - { "id": "U_kgDOBewVSw" }, - { "id": "U_kgDOCR6ywQ" } + { + "id": "MDQ6VXNlcjc0MjYzMw==" + }, + { + "id": "MDQ6VXNlcjEyMTU4NzM=" + }, + { + "id": "MDQ6VXNlcjE5Mzk4MTM=" + }, + { + "id": "MDQ6VXNlcjM4ODMyNDE=" + }, + { + "id": "MDQ6VXNlcjEyNjkxOTE4" + }, + { + "id": "MDQ6VXNlcjE5ODIxMTcx" + }, + { + "id": "MDQ6VXNlcjIxMTI5NjM5" + }, + { + "id": "MDQ6VXNlcjI1NDA0Nzgz" + }, + { + "id": "MDQ6VXNlcjM4OTYyMjQz" + }, + { + "id": "MDQ6VXNlcjQ2NjEyOTMz" + }, + { + "id": "MDQ6VXNlcjY4NDAzMzQw" + }, + { + "id": "U_kgDOBef8kg" + }, + { + "id": "U_kgDOBewVSw" + }, + { + "id": "U_kgDOCR6ywQ" + } ] } }, @@ -56,9 +112,15 @@ "name": "Hacky Hour", "members": { "nodes": [ - { "id": "MDQ6VXNlcjc0MjYzMw==" }, - { "id": "MDQ6VXNlcjY5NDcwODk=" }, - { "id": "MDQ6VXNlcjEyNjkxOTE4" } + { + "id": "MDQ6VXNlcjc0MjYzMw==" + }, + { + "id": "MDQ6VXNlcjY5NDcwODk=" + }, + { + "id": "MDQ6VXNlcjEyNjkxOTE4" + } ] } }, @@ -66,12 +128,37 @@ "name": "Coffee and Code", "members": { "nodes": [ - { "id": "MDQ6VXNlcjc0MjYzMw==" }, - { "id": "MDQ6VXNlcjEyMTU4NzM=" }, - { "id": "MDQ6VXNlcjEyNjkxOTE4" }, - { "id": "MDQ6VXNlcjIxMTI5NjM5" }, - { "id": "MDQ6VXNlcjI1NDA0Nzgz" }, - { "id": "U_kgDOBef8kg" } + { + "id": "MDQ6VXNlcjc0MjYzMw==" + }, + { + "id": "MDQ6VXNlcjEyMTU4NzM=" + }, + { + "id": "MDQ6VXNlcjEyNjkxOTE4" + }, + { + "id": "MDQ6VXNlcjIxMTI5NjM5" + }, + { + "id": "MDQ6VXNlcjI1NDA0Nzgz" + }, + { + "id": "U_kgDOBef8kg" + } + ] + } + }, + { + "name": "GitHub Admins", + "members": { + "nodes": [ + { + "id": "MDQ6VXNlcjc0MjYzMw==" + }, + { + "id": "U_kgDOBef8kg" + } ] } } @@ -86,7 +173,10 @@ "bio": "Organic Software Gardener 🍅", "company": "Exosphere Project", "avatarUrl": "https://avatars.githubusercontent.com/u/742633?u=204cc5138bfb07ef7332d3fa1d885bbbbe9e7281&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": "https://twitter.com/jpistorius", + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjEyMTU4NzM=", @@ -95,6 +185,7 @@ "bio": "I research how (and build software for!) people as they think about, reshape, and visualize data", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/1215873?u=9a4a9336866c4a348a0bb220a6e0490963bf32b5&v=4", + "websiteUrl": "https://alex-r-bigelow.github.io", "socialAccounts": { "edges": [ { @@ -113,6 +204,7 @@ "bio": "", "company": "University of Arizona", "avatarUrl": "https://avatars.githubusercontent.com/u/1939813?u=d39a4cac18c94ef60a298c2ad5fa82bb73fc30c3&v=4", + "websiteUrl": null, "socialAccounts": { "edges": [ { @@ -131,6 +223,7 @@ "bio": "Computing Sciences Researcher II at The University of Arizona.", "company": "The University of Arizona", "avatarUrl": "https://avatars.githubusercontent.com/u/3883241?u=bb818aa9153eb92f57ae7b878a39faed4988f025&v=4", + "websiteUrl": "https://soham.dev", "socialAccounts": { "edges": [ { @@ -149,15 +242,19 @@ "bio": "", "company": "Natural History Museum, University of Oslo", "avatarUrl": "https://avatars.githubusercontent.com/u/6617332?u=3836c3ffa014b36b188f4f45297f26461fb39a67&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": "https://sites.google.com/site/meghanbalk/", + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjY5NDcwODk=", "name": "Ryan Bartelme", "login": "rbartelme", - "bio": "Staff Data Scientist in biotechnology research and development", - "company": "Accelerate Diagnostics", + "bio": "Bioinformatician and Data Scientist in biotechnology research and development", + "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/6947089?u=9cc0c86dc9db92eb4358b6b9643b79db33b279f2&v=4", + "websiteUrl": "rbartelme.github.io", "socialAccounts": { "edges": [ { @@ -165,6 +262,12 @@ "provider": "TWITTER", "url": "https://twitter.com/MicrobialBart" } + }, + { + "node": { + "provider": "GENERIC", + "url": "https://bsky.app/profile/microbialbart.bsky.social" + } } ] } @@ -176,6 +279,7 @@ "bio": "-_-", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/7082025?v=4", + "websiteUrl": null, "socialAccounts": { "edges": [ { @@ -194,6 +298,7 @@ "bio": "", "company": "University of Arizona", "avatarUrl": "https://avatars.githubusercontent.com/u/10335479?u=b9414a8cb122c29d6c8544baea85a84c6baab939&v=4", + "websiteUrl": null, "socialAccounts": { "edges": [ { @@ -212,7 +317,10 @@ "bio": "I'm a code curious biologist.", "company": "University of Alabama at Birmingham", "avatarUrl": "https://avatars.githubusercontent.com/u/11023317?u=7200ca4bee6441f2ef582f70df5fe39bd236e3ee&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjExNTI3MDQx", @@ -221,6 +329,7 @@ "bio": "Director of Open Science & Associate Professor at the University of Arizona, Institute for Computation and Data Enabled Insight ", "company": "University of Arizona, CyVerse", "avatarUrl": "https://avatars.githubusercontent.com/u/11527041?u=2cefefd17d2dc2ec8243b7a1f53a620f1fde2ff4&v=4", + "websiteUrl": "tysonswetnam.com", "socialAccounts": { "edges": [ { @@ -245,6 +354,7 @@ "bio": "", "company": "University of Arizona, CCT Data Science", "avatarUrl": "https://avatars.githubusercontent.com/u/12022076?u=377f60f40b83a81b1e57ef8518406bc38ce6748f&v=4", + "websiteUrl": null, "socialAccounts": { "edges": [ { @@ -263,7 +373,10 @@ "bio": null, "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/12691918?u=a1c7d45e5755e99746ae358919406cc7f163b192&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjE5ODIxMTcx", @@ -272,7 +385,10 @@ "bio": "PhD Student at the University of Arizona's School of Information", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/19821171?u=3cca330b757c209c3c1547844a3ad81508304b58&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": "https://lwdozal.github.io/", + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjIwMzA1NzM0", @@ -281,6 +397,7 @@ "bio": "Staring at the universe's data in the dark.", "company": "Princeton Plasma Physics Lab; Steward Obs", "avatarUrl": "https://avatars.githubusercontent.com/u/20305734?u=84a111e22eef413d58e1370acea7cb12d075fc05&v=4", + "websiteUrl": "https://astrochun.github.io", "socialAccounts": { "edges": [ { @@ -297,9 +414,12 @@ "name": "Heidi Steiner", "login": "hidyverse", "bio": "", - "company": "University of Arizona", + "company": "@Boehringer-Ingelheim", "avatarUrl": "https://avatars.githubusercontent.com/u/21129639?u=f02dbb9a9ecfad325fa0ead8378f8d77f9150012&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjIyMzgxNTM2", @@ -308,7 +428,10 @@ "bio": "", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/22381536?u=5925008755e77dd5f884bd288ed6c0ff6f29a25d&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjI1MjM1MjI4", @@ -317,7 +440,10 @@ "bio": "Librarian @ University of Arizona\r\nDirector, Catalyst Studios\r\n@resbazaz organizer\r\n", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/25235228?u=84becdeac90a0ca8727cfcbfac7988ba13baca46&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjI1NDA0Nzgz", @@ -326,6 +452,7 @@ "bio": "Scientific Programmer & Educator at University of Arizona", "company": "University of Arizona, @cct-datascience", "avatarUrl": "https://avatars.githubusercontent.com/u/25404783?u=bf39b8163e91fb40423676c1806a9fc1ed665c0c&v=4", + "websiteUrl": "www.ericrscott.com", "socialAccounts": { "edges": [ { @@ -356,7 +483,10 @@ "bio": "", "company": "University of Arizona's iSchool", "avatarUrl": "https://avatars.githubusercontent.com/u/34466941?u=c00f55a3718179e6d8e73acf75d18f3373a59da9&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjM0NDg2MTU0", @@ -365,7 +495,10 @@ "bio": "Turkeys make excellent companions.", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/34486154?v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": "MagicMilly.github.io", + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjM2MTczNDkw", @@ -374,6 +507,7 @@ "bio": "Computational geneticist", "company": "NIH", "avatarUrl": "https://avatars.githubusercontent.com/u/36173490?v=4", + "websiteUrl": "https://www.linkedin.com/in/joanneberghout/", "socialAccounts": { "edges": [ { @@ -392,7 +526,10 @@ "bio": "Data Scientist | PhD, University of Arizona | R/RStudio Evangelist", "company": "University of Arizona", "avatarUrl": "https://avatars.githubusercontent.com/u/38962243?u=7ec452e5b8489ddbd966d22fdd5984332225c2ad&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": "https://gregtchism.com/", + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjQxNzA2OTE1", @@ -401,7 +538,10 @@ "bio": "", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/41706915?u=f94237b4dc3896de97d3fd66872ac172fb638337&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjQ2NjEyOTMz", @@ -410,7 +550,10 @@ "bio": "Astronomer, Data Scientist, Space Science & EO Enthusiast", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/46612933?v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjQ3NzY2MDc0", @@ -419,7 +562,10 @@ "bio": "", "company": "GSA", "avatarUrl": "https://avatars.githubusercontent.com/u/47766074?u=6e52d4344ed85cd5c8b5e873ec28f1d5e74907e9&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjU2NzAyNjAw", @@ -428,6 +574,7 @@ "bio": "", "company": "University of Arizona", "avatarUrl": "https://avatars.githubusercontent.com/u/56702600?u=03ece3573c51cb41e21197f7c2071d122d5e25a8&v=4", + "websiteUrl": "https://liaossanna.wixsite.com/liaos", "socialAccounts": { "edges": [ { @@ -446,7 +593,10 @@ "bio": null, "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/61329916?v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "MDQ6VXNlcjY4NDAzMzQw", @@ -455,6 +605,7 @@ "bio": "PhD Student in Ecological and Environmental Informatics,\r\nSchool of Informatics, Computing, and Cyber Systems\r\n \r\n\r\n", "company": "Northern Arizona University", "avatarUrl": "https://avatars.githubusercontent.com/u/68403340?u=d3e846be891006b37a7aae3b74c7ecde9d0ab6fd&v=4", + "websiteUrl": null, "socialAccounts": { "edges": [ { @@ -473,7 +624,10 @@ "bio": null, "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/72940286?u=c0d118c3c830aa038eb2993753b42979431b3dd2&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "U_kgDOBdICzA", @@ -482,7 +636,10 @@ "bio": "", "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/97649356?v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "U_kgDOBef8kg", @@ -491,7 +648,10 @@ "bio": "", "company": "University of Arizona", "avatarUrl": "https://avatars.githubusercontent.com/u/99089554?u=1441d55ea7637555aca31523963c26a68df6f57f&v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "U_kgDOBewVSw", @@ -500,7 +660,10 @@ "bio": null, "company": null, "avatarUrl": "https://avatars.githubusercontent.com/u/99358027?v=4", - "socialAccounts": { "edges": [] } + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } }, { "id": "U_kgDOCR6ywQ", @@ -508,8 +671,11 @@ "login": "ejahnUA", "bio": "", "company": "University of Arizona", - "avatarUrl": "https://avatars.githubusercontent.com/u/153006785?u=d14316c1567ab29135738cc82d41d37607b9963f&v=4", - "socialAccounts": { "edges": [] } + "avatarUrl": "https://avatars.githubusercontent.com/u/153006785?u=bafb3ce0c2ce02e9812c805a17950ab0e4445c83&v=4", + "websiteUrl": null, + "socialAccounts": { + "edges": [] + } } ] } diff --git a/img/logos/facebook.svg b/img/logos/facebook.svg new file mode 100644 index 0000000..2dc423e --- /dev/null +++ b/img/logos/facebook.svg @@ -0,0 +1,44 @@ + + diff --git a/img/logos/github.svg b/img/logos/github.svg new file mode 100644 index 0000000..14eab4d --- /dev/null +++ b/img/logos/github.svg @@ -0,0 +1,57 @@ + + diff --git a/img/logos/instagram.svg b/img/logos/instagram.svg new file mode 100644 index 0000000..e042935 --- /dev/null +++ b/img/logos/instagram.svg @@ -0,0 +1,101 @@ + + diff --git a/img/logos/link.svg b/img/logos/link.svg new file mode 100644 index 0000000..c15b509 --- /dev/null +++ b/img/logos/link.svg @@ -0,0 +1,70 @@ + + diff --git a/img/logos/linkedin.svg b/img/logos/linkedin.svg new file mode 100644 index 0000000..8e991c1 --- /dev/null +++ b/img/logos/linkedin.svg @@ -0,0 +1,54 @@ + + diff --git a/img/logos/mastodon.svg b/img/logos/mastodon.svg new file mode 100644 index 0000000..fdab6fc --- /dev/null +++ b/img/logos/mastodon.svg @@ -0,0 +1,47 @@ + + diff --git a/img/logos/pinterest.svg b/img/logos/pinterest.svg new file mode 100644 index 0000000..c52eefe --- /dev/null +++ b/img/logos/pinterest.svg @@ -0,0 +1,45 @@ + + diff --git a/img/logos/reddit.svg b/img/logos/reddit.svg new file mode 100644 index 0000000..0afe591 --- /dev/null +++ b/img/logos/reddit.svg @@ -0,0 +1,49 @@ + + diff --git a/img/logos/twitter.svg b/img/logos/twitter.svg new file mode 100644 index 0000000..802de75 --- /dev/null +++ b/img/logos/twitter.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + diff --git a/index.qmd b/index.qmd index abe590f..d43e252 100644 --- a/index.qmd +++ b/index.qmd @@ -10,7 +10,10 @@ title-block-banner-color: white --- ```{ojs} +import { combineAndOverrideGithubData } from './components/utilities.ojs'; import { randomAvatars } from './components/randomAvatars.ojs'; + +peopleData = combineAndOverrideGithubData(); ``` @@ -52,7 +55,7 @@ _(Optionally) RSVP for our events at Meetup: [Our MeetUp](https://www.meetup.com **Who you're likely to see**: ```{ojs} -randomAvatars("Coffee and Code"); +randomAvatars(peopleData, "coffee_and_code"); ``` ::: @@ -74,7 +77,7 @@ randomAvatars("Coffee and Code"); **Who you're likely to see**: ```{ojs} -randomAvatars("Hacky Hour"); +randomAvatars(peopleData, "hacky_hour"); ``` ::: @@ -99,7 +102,7 @@ randomAvatars("Hacky Hour"); **Who you're likely to see**: ```{ojs} -randomAvatars("Festival2024"); +randomAvatars(peopleData, "festival2024"); ``` ::: diff --git a/styles/whoWeAre.css b/styles/whoWeAre.css new file mode 100644 index 0000000..5e68464 --- /dev/null +++ b/styles/whoWeAre.css @@ -0,0 +1,8 @@ +.socialIcons { + display: flex; + gap: 0.5em; + margin: 0.5em 0; +} +.socialIcons a { + text-decoration: none !important; +} diff --git a/whoWeAre.qmd b/whoWeAre.qmd index a88c31a..197f383 100644 --- a/whoWeAre.qmd +++ b/whoWeAre.qmd @@ -1,20 +1,40 @@ --- layout: default +css: styles/whoWeAre.css execute: echo: false --- +::: { .column-screen-left } + ```{ojs} +// A lot of setup here, mostly so we can have a common state +// between nodeLinkDiagram and the sidebar +import { combineAndOverrideGithubData } from './components/utilities.ojs'; import { nodeLinkDiagram } from './components/nodeLinkDiagram.ojs'; +peopleData = combineAndOverrideGithubData(); + mutable selectedNode = null -``` -::: { .column-screen-left } -```{ojs} -render = nodeLinkDiagram(); -graph = render((node) => { +// On load, and when the back button is pressed, select the node indicated by the URL (if there is one) +function handleHashChange () { + mutable selectedNode = window.location.hash + ? peopleData.graph.nodes.find(node => node.hash === window.location.hash.slice(1)) || null + : null +} + +// More ojs weirdness: need to wrap event assignments in a cell +// or `undefined` will show up in the page +dummy = { + window.addEventListener('hashchange', handleHashChange); + window.addEventListener('load', handleHashChange); +} + +render = nodeLinkDiagram(peopleData.graph.nodes, peopleData.graph.links); +diagram = render((node) => { mutable selectedNode = node; + window.location.hash = node.hash; }, selectedNode); ``` ::: @@ -24,6 +44,9 @@ graph = render((node) => { { if (selectedNode === null) { return md` +This is a diagram of attendees, current and past organizers, and +their relationships to various ResBaz Arizona events. + *Click a node for more information* `; } else if (selectedNode.type === 'PERSON') { @@ -39,6 +62,20 @@ graph = render((node) => { const company = selectedNode.company ? md`*${selectedNode.company}*` : ''; + console.log(selectedNode); + + const extraSocialAccounts = selectedNode?.socialAccounts?.edges + ?.filter(edge => edge.node?.provider && edge.node?.url) + ?.map(edge => edge.node) || []; + const socialIconList = [ + ...(selectedNode?.websiteUrl ? [{ url: `https://github.com/${selectedNode.websiteUrl}`, provider: 'link' }] : []), + ...(selectedNode ? [{ url: `https://github.com/${selectedNode.login}`, provider: 'github' }] : []), + ...extraSocialAccounts, + ].map(account => html` + + `) || ''; + const socialIcons = html``; + // TODO: selectedNode.login for github link / icon, selectedNode.socialAccounts list for others const bio = selectedNode.bio ? md`${selectedNode.bio}` : ''; @@ -46,6 +83,7 @@ graph = render((node) => { return md` ${header} ${profilePic} +${socialIcons} ${company} ${bio} `; @@ -57,14 +95,4 @@ ${bio} }

`; } ``` -::: - -We're a community of current / former / aspirational researchers, data scientists, and friends helping each other to learn new technologies via various different events. - -This is a diagram of who is involved in our weekly meetups, and who has has put in the work to organize our bigger festival events. - -TODO: - -- Click nodes to learn more! - - Highlight clicked nodes, show selected event / github profile links -- Prettier links, fonts \ No newline at end of file +::: \ No newline at end of file From dcd787ff4238aa757fc48a7d7eb035784a61c244 Mon Sep 17 00:00:00 2001 From: Alex Bigelow Date: Fri, 5 Apr 2024 14:59:42 -0700 Subject: [PATCH 5/5] Cleanup test team --- data/overrides.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/data/overrides.json b/data/overrides.json index 13d5699..f0346e0 100644 --- a/data/overrides.json +++ b/data/overrides.json @@ -3,10 +3,6 @@ "festival2024": { "name": "2024 Festival Organizers" }, - "TestTeam": { - "name": "Test Team", - "members": ["alex-r-bigelow"] - }, "coffee_and_code": { "type": "WEEKLY" },