Skip to content

Instantly share code, notes, and snippets.

@allisonking
Last active August 1, 2020 18:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allisonking/91ead93b3e348531a91c53a3427b0d1b to your computer and use it in GitHub Desktop.
Save allisonking/91ead93b3e348531a91c53a3427b0d1b to your computer and use it in GitHub Desktop.
Using saved points from a force directed graph

This is part two of using d3.js's force directed graph to create a customized static layout. Part 1 is here. The file character_nodes.json was the result of moving each node and Bezier control point around until the graph looked reasonable, then printing it out as described in part 1.

{"nodes":[{"id":"Harry P.","generation":"main_gen","house":"Gryffindor","index":0,"x":540.8028920512572,"y":167.40616031371894,"vy":0,"vx":0,"fx":540.8028920512572,"fy":167.40616031371894},{"id":"Hermione G.","generation":"main_gen","house":"Gryffindor","index":1,"x":626.4472475635683,"y":333.0535822114966,"vy":0,"vx":0,"fx":626.4472475635683,"fy":333.0535822114966},{"id":"Draco M.","generation":"main_gen","house":"Slytherin","index":2,"x":725.9534615882674,"y":354.7772639487501,"vy":0,"vx":0,"fx":725.9534615882674,"fy":354.7772639487501},{"id":"Severus S.","generation":"marauder_gen","house":"Slytherin","index":3,"x":372.7846213941932,"y":249.21153196277896,"vy":0,"vx":0,"fx":372.7846213941932,"fy":249.21153196277896},{"id":"Lily Evans P.","generation":"marauder_gen","house":"Gryffindor","index":4,"x":497.8489676928216,"y":55.81006152106502,"vy":0,"vx":0,"fx":497.8489676928216,"fy":55.81006152106502},{"id":"James P.","generation":"marauder_gen","house":"Gryffindor","index":5,"x":367.5588060068456,"y":48.85010531162018,"vy":0,"vx":0,"fx":367.5588060068456,"fy":48.85010531162018},{"id":"Sirius B.","generation":"marauder_gen","house":"Gryffindor","index":6,"x":422.3915268722183,"y":128.65490867905217,"vy":0,"vx":0,"fx":422.3915268722183,"fy":128.65490867905217},{"id":"Ginny W.","generation":"main_gen","house":"Gryffindor","index":7,"x":710.6377875497316,"y":190.65369739207858,"vy":0,"vx":0,"fx":710.6377875497316,"fy":190.65369739207858},{"id":"Ron W.","generation":"main_gen","house":"Gryffindor","index":8,"x":624.9867914789204,"y":172.36422477790234,"vy":0,"vx":0,"fx":624.9867914789204,"fy":172.36422477790234},{"id":"Remus L.","generation":"marauder_gen","house":"Gryffindor","index":9,"x":276.64785910370637,"y":136.36704172367126,"vy":0,"vx":0,"fx":276.64785910370637,"fy":136.36704172367126},{"id":"OC","generation":"other","house":"other","index":10,"x":536.1457894777545,"y":349.2700596495804,"vy":0,"vx":0,"fx":536.1457894777545,"fy":349.2700596495804},{"id":"Scorpius M.","generation":"next_gen","house":"other","index":11,"x":679.5132030387393,"y":445.80696620867724,"vy":0,"vx":0,"fx":679.5132030387393,"fy":445.80696620867724},{"id":"Voldemort","generation":"riddle_gen","house":"Slytherin","index":12,"x":343.647912632863,"y":363.7196211661951,"vy":0,"vx":0,"fx":343.647912632863,"fy":363.7196211661951},{"id":"George W.","generation":"main_gen","house":"Gryffindor","index":13,"x":453.56441556997487,"y":427.28965903862377,"vy":0,"vx":0,"fx":453.56441556997487,"fy":427.28965903862377},{"id":"Luna L.","generation":"main_gen","house":"Gryffindor","index":14,"x":756.5921621293056,"y":256.31544393802466,"vy":0,"vx":0,"fx":756.5921621293056,"fy":256.31544393802466},{"id":"Fred W.","generation":"main_gen","house":"Gryffindor","index":15,"x":518.5628391596379,"y":430.4423566713688,"vy":0,"vx":0,"fx":518.5628391596379,"fy":430.4423566713688},{"id":"Albus D.","generation":"riddle_gen","house":"Gryffindor","index":16,"x":286.1374164053055,"y":340.587630385697,"vy":0,"vx":0,"fx":286.1374164053055,"fy":340.587630385697},{"id":"Rose W.","generation":"next_gen","house":"other","index":17,"x":614.1843402146427,"y":452.13948842700785,"vy":0,"vx":0,"fx":614.1843402146427,"fy":452.13948842700785},{"id":"N. Tonks","generation":"main_gen","house":"Hufflepuff","index":18,"x":273.51798938762295,"y":226.60359958364361,"vy":0,"vx":0,"fx":273.51798938762295,"fy":226.60359958364361},{"id":"Tom R. Jr.","generation":"riddle_gen","house":"Slytherin","index":19,"x":399.86045657968725,"y":325.6815175718059,"vy":0,"vx":0,"fx":399.86045657968725,"fy":325.6815175718059},{"id":"Albus S. P.","generation":"next_gen","house":"other","index":20,"x":668.7480188421613,"y":550.1766281548474,"vy":0,"vx":0,"fx":668.7480188421613,"fy":550.1766281548474},{"id":"Lily Luna P.","generation":"next_gen","house":"other","index":21,"x":776.8066894910385,"y":489.4827778482122,"vy":0,"vx":0,"fx":776.8066894910385,"fy":489.4827778482122},{"id":"Bellatrix L.","generation":"marauder_gen","house":"Slytherin","index":22,"x":369.6862218045012,"y":432.10429658479114,"vy":0,"vx":0,"fx":369.6862218045012,"fy":432.10429658479114},{"id":"Angelina J.","generation":"main_gen","house":"Gryffindor","index":23,"x":498.23803534217257,"y":502.00867949551633,"vy":0,"vx":0,"fx":498.23803534217257,"fy":502.00867949551633},{"id":"Neville L.","generation":"main_gen","house":"Gryffindor","index":24,"x":842.4754718509021,"y":212.38949115162518,"vy":0,"vx":0,"fx":842.4754718509021,"fy":212.38949115162518},{"id":"Minerva M.","generation":"riddle_gen","house":"Gryffindor","index":25,"x":237.40325895249657,"y":406.84522552818174,"vy":0,"vx":0,"fx":237.40325895249657,"fy":406.84522552818174},{"id":"Gellert G.","generation":"riddle_gen","house":"other","index":26,"x":205.13566722809634,"y":370.5526058602147,"vy":0,"vx":0,"fx":205.13566722809634,"fy":370.5526058602147},{"id":"James S. P.","generation":"next_gen","house":"other","index":27,"x":575.0113358386595,"y":539.1669807588935,"vy":0,"vx":0,"fx":575.0113358386595,"fy":539.1669807588935},{"id":"Charlie W.","generation":"main_gen","house":"Gryffindor","index":28,"x":196.3739340023526,"y":251.08043108789053,"vy":0,"vx":0,"fx":196.3739340023526,"fy":251.08043108789053}],"intermediates":[{"index":29,"x":612.1632238847769,"y":250.41728107004832,"vy":0,"vx":0,"fx":612.1632238847769,"fy":250.41728107004832},{"index":30,"x":568.1810395210173,"y":260.98822496567453,"vy":0,"vx":0,"fx":568.1810395210173,"fy":260.98822496567453},{"index":31,"x":673.9868562129759,"y":110.20026654425098,"vy":0,"vx":0,"fx":673.9868562129759,"fy":110.20026654425098},{"index":32,"x":349.04219569250654,"y":234.55603604937764,"vy":0,"vx":0,"fx":349.04219569250654,"fy":234.55603604937764},{"index":33,"x":583.9937933006844,"y":170.3348658997105,"vy":0,"vx":0,"fx":583.9937933006844,"fy":170.3348658997105},{"index":34,"x":630.4632509296423,"y":347.16037937968485,"vy":0,"vx":0,"fx":630.4632509296423,"fy":347.16037937968485},{"index":35,"x":615.6312102004513,"y":286.40829012892425,"vy":0,"vx":0,"fx":615.6312102004513,"fy":286.40829012892425},{"index":36,"x":460.68930594177607,"y":274.01127099440174,"vy":0,"vx":0,"fx":460.68930594177607,"fy":274.01127099440174},{"index":37,"x":639.5834239274718,"y":270.2202029982587,"vy":0,"vx":0,"fx":639.5834239274718,"fy":270.2202029982587},{"index":38,"x":744.0822457578663,"y":294.3361782656955,"vy":0,"vx":0,"fx":744.0822457578663,"fy":294.3361782656955},{"index":39,"x":642.2165169207249,"y":388.9605539330341,"vy":0,"vx":0,"fx":642.2165169207249,"fy":388.9605539330341},{"index":40,"x":698.4395504908757,"y":252.26379376585402,"vy":0,"vx":0,"fx":698.4395504908757,"fy":252.26379376585402},{"index":41,"x":486.63874556209925,"y":157.69250854745403,"vy":0,"vx":0,"fx":486.63874556209925,"fy":157.69250854745403},{"index":42,"x":422.04019737300086,"y":353.50620999194433,"vy":0,"vx":0,"fx":422.04019737300086,"fy":353.50620999194433},{"index":43,"x":318.8319476219532,"y":189.88814676608882,"vy":0,"vx":0,"fx":318.8319476219532,"fy":189.88814676608882},{"index":44,"x":435.9519172207938,"y":26.07121680017093,"vy":0,"vx":0,"fx":435.9519172207938,"fy":26.07121680017093},{"index":45,"x":429.23728980169363,"y":92.1289439549767,"vy":0,"vx":0,"fx":429.23728980169363,"fy":92.1289439549767},{"index":46,"x":315.5708591908132,"y":116.5053188971989,"vy":0,"vx":0,"fx":315.5708591908132,"fy":116.5053188971989},{"index":47,"x":553.3362342057757,"y":100.17014239169944,"vy":0,"vx":0,"fx":553.3362342057757,"fy":100.17014239169944},{"index":48,"x":404.9037551389904,"y":102.91917073431964,"vy":0,"vx":0,"fx":404.9037551389904,"fy":102.91917073431964},{"index":49,"x":293.5308352656019,"y":71.95543798537017,"vy":0,"vx":0,"fx":293.5308352656019,"fy":71.95543798537017},{"index":50,"x":413.76824610836644,"y":74.25323567707959,"vy":0,"vx":0,"fx":413.76824610836644,"fy":74.25323567707959},{"index":51,"x":345.1257602970906,"y":175.81965191946315,"vy":0,"vx":0,"fx":345.1257602970906,"fy":175.81965191946315},{"index":52,"x":378.4741537428859,"y":140.26167553441417,"vy":0,"vx":0,"fx":378.4741537428859,"fy":140.26167553441417},{"index":53,"x":481.0813143495071,"y":149.61214012659087,"vy":0,"vx":0,"fx":481.0813143495071,"fy":149.61214012659087},{"index":54,"x":462.0677373878709,"y":250.13287038458043,"vy":0,"vx":0,"fx":462.0677373878709,"fy":250.13287038458043},{"index":55,"x":667.5095040538873,"y":177.5335154336335,"vy":0,"vx":0,"fx":667.5095040538873,"fy":177.5335154336335},{"index":56,"x":508.546876800576,"y":202.39880725727312,"vy":0,"vx":0,"fx":508.546876800576,"fy":202.39880725727312},{"index":57,"x":553.6496852683767,"y":266.6042902462571,"vy":0,"vx":0,"fx":553.6496852683767,"fy":266.6042902462571},{"index":58,"x":276.52184523552455,"y":179.5577121740141,"vy":0,"vx":0,"fx":276.52184523552455,"fy":179.5577121740141},{"index":59,"x":403.2777896560773,"y":192.56360237599526,"vy":0,"vx":0,"fx":403.2777896560773,"fy":192.56360237599526},{"index":60,"x":541.1184110535127,"y":229.4127563534147,"vy":0,"vx":0,"fx":541.1184110535127,"fy":229.4127563534147},{"index":61,"x":533.2827900857457,"y":334.53936896471214,"vy":0,"vx":0,"fx":533.2827900857457,"fy":334.53936896471214},{"index":62,"x":643.7989387492973,"y":452.2751150139631,"vy":0,"vx":0,"fx":643.7989387492973,"fy":452.2751150139631},{"index":63,"x":694.7040230398111,"y":485.0124802553521,"vy":0,"vx":0,"fx":694.7040230398111,"fy":485.0124802553521},{"index":64,"x":747.6755892150824,"y":452.914104139382,"vy":0,"vx":0,"fx":747.6755892150824,"fy":452.914104139382},{"index":65,"x":700.9684990625966,"y":407.5954552305241,"vy":0,"vx":0,"fx":700.9684990625966,"fy":407.5954552305241},{"index":66,"x":660.4814463584511,"y":406.5916493841645,"vy":0,"vx":0,"fx":660.4814463584511,"fy":406.5916493841645},{"index":67,"x":406.5478196869361,"y":270.3274020502485,"vy":0,"vx":0,"fx":406.5478196869361,"fy":270.3274020502485},{"index":68,"x":338.1731778446993,"y":401.21306994784425,"vy":0,"vx":0,"fx":338.1731778446993,"fy":401.21306994784425},{"index":69,"x":367.7699932407624,"y":347.0757223401148,"vy":0,"vx":0,"fx":367.7699932407624,"fy":347.0757223401148},{"index":70,"x":348.5397172832171,"y":321.68897764077667,"vy":0,"vx":0,"fx":348.5397172832171,"fy":321.68897764077667},{"index":71,"x":416.74435308427843,"y":434.72082210778785,"vy":0,"vx":0,"fx":416.74435308427843,"fy":434.72082210778785},{"index":72,"x":493.5206316671319,"y":429.4037028887106,"vy":0,"vx":0,"fx":493.5206316671319,"fy":429.4037028887106},{"index":73,"x":488.62534074809014,"y":395.20732347364566,"vy":0,"vx":0,"fx":488.62534074809014,"fy":395.20732347364566},{"index":74,"x":482.7864380564855,"y":367.0376630333279,"vy":0,"vx":0,"fx":482.7864380564855,"fy":367.0376630333279},{"index":75,"x":470.2139953415309,"y":465.81781183895083,"vy":0,"vx":0,"fx":470.2139953415309,"fy":465.81781183895083},{"index":76,"x":443.8180997238403,"y":319.1077058233291,"vy":0,"vx":0,"fx":443.8180997238403,"fy":319.1077058233291},{"index":77,"x":783.6384682695142,"y":51.51520017459717,"vy":0,"vx":0,"fx":783.6384682695142,"fy":51.51520017459717},{"index":78,"x":796.3168131153229,"y":209.67420557787858,"vy":0,"vx":0,"fx":796.3168131153229,"fy":209.67420557787858},{"index":79,"x":757.6423148687228,"y":318.173256402444,"vy":0,"vx":0,"fx":757.6423148687228,"fy":318.173256402444},{"index":80,"x":701.8279069473415,"y":306.62575547390986,"vy":0,"vx":0,"fx":701.8279069473415,"fy":306.62575547390986},{"index":81,"x":751.1793370334192,"y":206.88780153543013,"vy":0,"vx":0,"fx":751.1793370334192,"fy":206.88780153543013},{"index":82,"x":596.9955612577992,"y":390.3802164075189,"vy":0,"vx":0,"fx":596.9955612577992,"fy":390.3802164075189},{"index":83,"x":529.9037776136463,"y":405.268035007363,"vy":0,"vx":0,"fx":529.9037776136463,"fy":405.268035007363},{"index":84,"x":479.1501277855045,"y":336.60525317251256,"vy":0,"vx":0,"fx":479.1501277855045,"fy":336.60525317251256},{"index":85,"x":524.6377659064744,"y":472.055881392689,"vy":0,"vx":0,"fx":524.6377659064744,"fy":472.055881392689},{"index":86,"x":273.52296484522293,"y":369.61961504545206,"vy":0,"vx":0,"fx":273.52296484522293,"fy":369.61961504545206},{"index":87,"x":344.9517065360453,"y":302.0121109650102,"vy":0,"vx":0,"fx":344.9517065360453,"fy":302.0121109650102},{"index":88,"x":304.3403553900821,"y":275.84330984888527,"vy":0,"vx":0,"fx":304.3403553900821,"fy":275.84330984888527},{"index":89,"x":297.1388518177573,"y":318.0817859872735,"vy":0,"vx":0,"fx":297.1388518177573,"fy":318.0817859872735},{"index":90,"x":314.272259377381,"y":359.0055277157646,"vy":0,"vx":0,"fx":314.272259377381,"fy":359.0055277157646},{"index":91,"x":647.6032320362458,"y":497.9768308999661,"vy":0,"vx":0,"fx":647.6032320362458,"fy":497.9768308999661},{"index":92,"x":576.0153217760537,"y":486.9930867713214,"vy":0,"vx":0,"fx":576.0153217760537,"fy":486.9930867713214},{"index":93,"x":609.9756707882364,"y":423.88336687536014,"vy":0,"vx":0,"fx":609.9756707882364,"fy":423.88336687536014},{"index":94,"x":569.7032041524526,"y":439.901704412571,"vy":0,"vx":0,"fx":569.7032041524526,"fy":439.901704412571},{"index":95,"x":318.26347103993874,"y":237.78911987368545,"vy":0,"vx":0,"fx":318.26347103993874,"fy":237.78911987368545},{"index":96,"x":367.9474463287112,"y":191.5283337068945,"vy":0,"vx":0,"fx":367.9474463287112,"fy":191.5283337068945},{"index":97,"x":249.69136197123822,"y":233.04711588642408,"vy":0,"vx":0,"fx":249.69136197123822,"fy":233.04711588642408},{"index":98,"x":349.82682609641864,"y":253.20351354027184,"vy":0,"vx":0,"fx":349.82682609641864,"fy":253.20351354027184},{"index":99,"x":476.52423860064937,"y":242.70131279220936,"vy":0,"vx":0,"fx":476.52423860064937,"fy":242.70131279220936},{"index":100,"x":544.7148650961258,"y":319.392188063221,"vy":0,"vx":0,"fx":544.7148650961258,"fy":319.392188063221},{"index":101,"x":440.21843468751575,"y":366.61079744138345,"vy":0,"vx":0,"fx":440.21843468751575,"fy":366.61079744138345}],"links":[{"source":"Harry P.","target":"Draco M.","value":34761},{"source":"Harry P.","target":"Hermione G.","value":27888},{"source":"Harry P.","target":"Ginny W.","value":22153},{"source":"Harry P.","target":"Severus S.","value":12273},{"source":"Harry P.","target":"Ron W.","value":9173},{"source":"Hermione G.","target":"Draco M.","value":44837},{"source":"Hermione G.","target":"Ron W.","value":26687},{"source":"Hermione G.","target":"Severus S.","value":11213},{"source":"Hermione G.","target":"Ginny W.","value":3583},{"source":"Draco M.","target":"Ginny W.","value":12946},{"source":"Draco M.","target":"OC","value":4130},{"source":"Draco M.","target":"Ron W.","value":2612},{"source":"Severus S.","target":"Lily Evans P.","value":6619},{"source":"Severus S.","target":"OC","value":2816},{"source":"Severus S.","target":"Remus L.","value":2149},{"source":"Lily Evans P.","target":"James P.","value":33888},{"source":"Lily Evans P.","target":"Sirius B.","value":3648},{"source":"Lily Evans P.","target":"Remus L.","value":2285},{"source":"Lily Evans P.","target":"Harry P.","value":2221},{"source":"James P.","target":"Sirius B.","value":8342},{"source":"James P.","target":"Remus L.","value":3620},{"source":"James P.","target":"Harry P.","value":2593},{"source":"James P.","target":"Severus S.","value":1247},{"source":"Sirius B.","target":"Remus L.","value":17923},{"source":"Sirius B.","target":"Harry P.","value":4805},{"source":"Sirius B.","target":"OC","value":4161},{"source":"Ginny W.","target":"Ron W.","value":1646},{"source":"Ginny W.","target":"Tom R. Jr.","value":947},{"source":"Ron W.","target":"OC","value":747},{"source":"Remus L.","target":"N. Tonks","value":6008},{"source":"Remus L.","target":"Harry P.","value":2189},{"source":"OC","target":"Harry P.","value":6345},{"source":"OC","target":"Hermione G.","value":1795},{"source":"Scorpius M.","target":"Rose W.","value":7893},{"source":"Scorpius M.","target":"Albus S. P.","value":3316},{"source":"Scorpius M.","target":"Lily Luna P.","value":1808},{"source":"Scorpius M.","target":"Draco M.","value":930},{"source":"Scorpius M.","target":"OC","value":690},{"source":"Voldemort","target":"Harry P.","value":5256},{"source":"Voldemort","target":"Bellatrix L.","value":1255},{"source":"Voldemort","target":"Tom R. Jr.","value":796},{"source":"Voldemort","target":"Severus S.","value":756},{"source":"Voldemort","target":"Hermione G.","value":615},{"source":"George W.","target":"Fred W.","value":4824},{"source":"George W.","target":"Hermione G.","value":1699},{"source":"George W.","target":"OC","value":1239},{"source":"George W.","target":"Angelina J.","value":910},{"source":"George W.","target":"Harry P.","value":810},{"source":"Luna L.","target":"Harry P.","value":2821},{"source":"Luna L.","target":"Neville L.","value":1929},{"source":"Luna L.","target":"Draco M.","value":1800},{"source":"Luna L.","target":"Hermione G.","value":1004},{"source":"Luna L.","target":"Ginny W.","value":942},{"source":"Fred W.","target":"Hermione G.","value":3017},{"source":"Fred W.","target":"OC","value":1568},{"source":"Fred W.","target":"Harry P.","value":646},{"source":"Fred W.","target":"Angelina J.","value":549},{"source":"Albus D.","target":"Minerva M.","value":2941},{"source":"Albus D.","target":"Harry P.","value":2239},{"source":"Albus D.","target":"Severus S.","value":1948},{"source":"Albus D.","target":"Gellert G.","value":662},{"source":"Albus D.","target":"Voldemort","value":445},{"source":"Rose W.","target":"Albus S. P.","value":1580},{"source":"Rose W.","target":"James S. P.","value":584},{"source":"Rose W.","target":"Hermione G.","value":508},{"source":"Rose W.","target":"OC","value":504},{"source":"N. Tonks","target":"Harry P.","value":572},{"source":"N. Tonks","target":"Sirius B.","value":350},{"source":"N. Tonks","target":"Charlie W.","value":328},{"source":"N. Tonks","target":"Severus S.","value":260},{"source":"Tom R. Jr.","target":"Harry P.","value":2278},{"source":"Tom R. Jr.","target":"Hermione G.","value":1140},{"source":"Tom R. Jr.","target":"OC","value":926}]}
function Graph(options) {
var svg = d3.select(options.container),
width = +svg.attr("width"),
height = +svg.attr("height");
var colorMap = {
'Gryffindor' : 'red',
'Slytherin' : 'green',
'Hufflepuff' : '#ffd700',
'Ravenclaw' : 'blue',
'other' : 'grey'
}
var linkScale = d3.scaleLog()
.range([1, 6])
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().distance(20).strength(0.5))
.force("charge", d3.forceManyBody().strength(-25))
.force("center", d3.forceCenter(width / 2, height / 2));
d3.json("character_nodes.json", function(error, graph) {
if (error) throw error;
var nodes = graph.nodes,
num_characters = nodes.length;
intermediates = graph.intermediates,
nodeById = d3.map(nodes, function(d) { return d.id; }),
nodeByIndex = d3.map(intermediates, function(d) { return d.index;})
links = graph.links,
bilinks = [],
links.forEach(function(link, index) {
var s = link.source = nodeById.get(link.source),
t = link.target = nodeById.get(link.target),
v = +link.value,
// intermediate will now be read in as opposed to empty
i = nodeByIndex.get(index + num_characters);
nodes.push(i);
links.push({source: s, target: i}, {source: i, target: t});
bilinks.push([s, i, t, v]);
});
linkScale.domain([d3.min(bilinks, function(d) { return d[3]; }),
d3.max(bilinks, function(d) { return d[3]; })]);
var link = svg.selectAll(".link")
.data(bilinks)
.enter().append("path")
.attr("class", "link")
.attr('stroke-width', function(d) {
return linkScale(d[3]);
})
.style('stroke', 'grey')
.on('mouseover', handleLinkMouseOver)
.on('mouseout', handleLinkMouseOut);
link.append('svg:title')
.text(function(d){ return d[3]; });
var node = svg.selectAll('.node')
.data(nodes.filter(function(d) { return d.id; }))
.enter().append('g')
.attr('class', 'node')
.on('mouseover', handleNodeMouseOver)
.on('mouseout', handleNodeMouseOut)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged));
node.append('circle')
.attr('r', 20)
.style("stroke", function(d) { return colorMap[d.house]; })
.style('stroke-width', 2)
.attr('fill', 'white');
node.append('text')
.attr('class', 'node-label')
.attr('fill', 'black')
.attr('y', function(d) { return '.35em'})
.attr('text-anchor', 'middle')
.text(function(d) { return getInitials(d.id)});
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
function ticked() {
link.attr("d", positionLink);
node.attr("transform", positionNode);
}
});
function getInitials(name) {
if(name == 'OC') return name;
var initials = "";
var split = name.split(" ");
split.forEach(function(partial_name) {
initials = initials + partial_name[0];
})
return initials;
}
function positionLink(d) {
return "M" + d[0].x + "," + d[0].y
+ "S" + d[1].x + "," + d[1].y
+ " " + d[2].x + "," + d[2].y;
}
function positionNode(d) {
return "translate(" + d.x + "," + d.y + ")";
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x, d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x, d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null, d.fy = null;
}
function handleNodeMouseOver(d) {
d3.select(this)
.select('text')
.text(d.id);
d3.selectAll('.link')
.filter(function(link) {
return link[0].id == d.id || link[2].id == d.id;
})
.style('stroke', 'rgb(50, 118, 231)');
}
function handleNodeMouseOut(d) {
d3.select(this)
.select('text')
.text(getInitials(d.id));
d3.selectAll('.link')
.style('stroke', 'grey');
}
function handleLinkMouseOver(d) {
d3.select(this)
.style('stroke', 'rgb(50, 118, 231)')
d3.selectAll('.node')
.filter(function(node) {
return node.id == d[0].id || node.id == d[2].id;
})
.selectAll('circle')
.style('stroke-width', 5);
}
function handleLinkMouseOut(d) {
d3.select(this)
.style('stroke', 'grey');
d3.selectAll('.node')
.selectAll('circle')
.style('stroke-width', 2);
}
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.link {
fill: none;
}
</style>
<svg width="960" height="600" id="graph-container"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src='graph.js'></script>
<script>
Graph({
container: "#graph-container"
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment