Skip to content

Instantly share code, notes, and snippets.

@ps23
Last active August 4, 2017 23:06

Revisions

  1. Patrick Seidler revised this gist Aug 4, 2017. 5 changed files with 320 additions and 759 deletions.
    762 changes: 36 additions & 726 deletions data.json
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,5 @@
    {
    "defs": {
    "highlight": {
    "color1": "#22929E",
    "color2": "#22929E",
    "label": "H"
    },
    "nominal": {
    "color1": "#8DA0CB",
    "color2": "#FC8D62",
    @@ -15,762 +10,77 @@
    "color2": "#FC8D62",
    "label": "CR"
    },
    "locationrecord": {
    "location": {
    "color1": "#D870AD",
    "color2": "#D870AD",
    "label": "L"
    },
    "comctrl": {
    "color1": "#EBC24F",
    "color2": "#FC8D62",
    "label": "CO"
    },
    "intel": {
    "color1": "#B2DF8A",
    "color2": "#FC8D62",
    "label": "I"
    },
    "cam": {
    "color1": "#9BA37E",
    "color2": "#FC8D62",
    "label": "CA"
    }
    },
    "nodes": [
    {
    "level": "lev1",
    "id": "170135094",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "151390617",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "181013990",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "246866328",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "248643355",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "247687095",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "199034696",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "237148781",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "169599424",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "171776080",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "249115457",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "244037963",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "247481321",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "241249876",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "165925084",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "240137299",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "240137162",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "197404396",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "231180787",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "245082862",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "169004159",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "195340354",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "DOE_PARK-CARSINGTON",
    "type": "locationrecord"
    },
    {
    "level": "lev1",
    "id": "247740388",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "237314688",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "156923636",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "246850984",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "233248939",
    "id": "http://ns.valcri.org/data/crimes#crime138640301",
    "label": "138640301",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "171428100",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "247112380",
    "type": "crime"
    "hasTown": "CARSINGTON",
    "hasStreet": "PEARN ROAD",
    "id": "http://ns.valcri.org/data/locations#-1_8130219_52_46728",
    "label": "http://ns.valcri.org/data/locations#-1_8130219_52_46728",
    "type": "location",
    "long": 52.467281341552734,
    "lat": -1.8130218982696533
    },
    {
    "level": "lev1",
    "id": "244623638",
    "id": "http://ns.valcri.org/data/crimes#crime162033325",
    "hasLocation": "http://ns.valcri.org/data/locations#-1_8130219_52_46728",
    "label": "162033325",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "23571299T",
    "victimOf": "http://ns.valcri.org/data/crimes#crime162033325",
    "id": "http://ns.valcri.org/data/nominals#nominal9084944P",
    "label": "9084944P",
    "hasHome": "http://ns.valcri.org/data/locations#-1_8130219_52_46728",
    "type": "nominal"
    },
    {
    "level": "lev1",
    "id": "238573307",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "233312507",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "243422559",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "183278463",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "238492751",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "145384537",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "180971246",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "249641537",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "246709463",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "232703405",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "166652691",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "WELLGREEN_ROAD-CARSINGTON",
    "type": "locationrecord"
    },
    {
    "level": "lev1",
    "id": "205400264",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "234934587",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "169220208",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "245839513",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "230235761",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "249389320",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "185286609",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "239263239",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "244928052",
    "type": "crime"
    }
    ],
    "links": [
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "sourceType": "crime",
    "sourceLabel": "162033325",
    "targetLabel": "http://ns.valcri.org/data/locations#-1_8130219_52_46728",
    "targetType": "location",
    "id": "link0",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "205400264"
    "source": "http://ns.valcri.org/data/crimes#crime162033325",
    "target": "http://ns.valcri.org/data/locations#-1_8130219_52_46728"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "sourceLabel": "9084944P",
    "targetLabel": "138640301",
    "targetType": "crime",
    "id": "link1",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "169599424"
    "source": "http://ns.valcri.org/data/nominals#nominal9084944P",
    "target": "http://ns.valcri.org/data/crimes#crime138640301"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "sourceLabel": "9084944P",
    "targetLabel": "162033325",
    "targetType": "crime",
    "id": "link2",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "232703405"
    "source": "http://ns.valcri.org/data/nominals#nominal9084944P",
    "target": "http://ns.valcri.org/data/crimes#crime162033325"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "sourceLabel": "9084944P",
    "targetLabel": "http://ns.valcri.org/data/locations#-1_8130219_52_46728",
    "targetType": "location",
    "id": "link3",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "245082862"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link4",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "246866328"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link5",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "195340354"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link6",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "246850984"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link7",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "233312507"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link8",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "145384537"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link9",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "249641537"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link10",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "246709463"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link11",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "244623638"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link12",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "249389320"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link13",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "197404396"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link14",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "185286609"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link15",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "199034696"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link16",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "170135094"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link17",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "243422559"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link18",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "233248939"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link19",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "169220208"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link20",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "166652691"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link21",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "165925084"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link22",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "230235761"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link23",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "240137162"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link24",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "244928052"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link25",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247481321"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link26",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "171428100"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link27",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "244037963"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link28",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "231180787"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link29",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "181013990"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link30",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "237148781"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link31",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247112380"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link32",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "241249876"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link33",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "169004159"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link34",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "171776080"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link35",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "249115457"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link36",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247687095"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link37",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "238573307"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link38",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "239263239"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link39",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247740388"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link40",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "183278463"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link41",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "237314688"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link42",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "240137299"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link43",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "238492751"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link44",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "234934587"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link45",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "180971246"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link46",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "248643355"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link47",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "151390617"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link48",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "156923636"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link49",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "245839513"
    },
    {
    "sourceType": "crime",
    "level": "lev1",
    "targetType": "locationrecord",
    "id": "link50",
    "source": "170135094",
    "type": "http://example.org#hasLocation",
    "target": "DOE_PARK-CARSINGTON"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "locationrecord",
    "id": "link51",
    "source": "23571299T",
    "type": "http://example.org#hasHome",
    "target": "WELLGREEN_ROAD-CARSINGTON"
    "source": "http://ns.valcri.org/data/nominals#nominal9084944P",
    "target": "http://ns.valcri.org/data/locations#-1_8130219_52_46728"
    }
    ]
    }
    131 changes: 131 additions & 0 deletions data_add1.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,131 @@
    {
    "nodes": [
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime126467988",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal7860282G",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime124047883",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal82376756A",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime127780722",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal8456992G",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime144160853",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal87105490C",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime156633059",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal93487729Z",
    "type": "nominal"
    }
    ],
    "links": [
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime162033325",
    "target": "http://ns.valcri.org/data/crimes#crime126467988"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime126467988",
    "target": "http://ns.valcri.org/data/nominals#nominal7860282G"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime162033325",
    "target": "http://ns.valcri.org/data/crimes#crime124047883"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime124047883",
    "target": "http://ns.valcri.org/data/nominals#nominal82376756A"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime162033325",
    "target": "http://ns.valcri.org/data/crimes#crime127780722"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime127780722",
    "target": "http://ns.valcri.org/data/nominals#nominal8456992G"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime162033325",
    "target": "http://ns.valcri.org/data/crimes#crime144160853"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime144160853",
    "target": "http://ns.valcri.org/data/nominals#nominal87105490C"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime162033325",
    "target": "http://ns.valcri.org/data/crimes#crime156633059"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime156633059",
    "target": "http://ns.valcri.org/data/nominals#nominal93487729Z"
    }
    ]
    }
    131 changes: 131 additions & 0 deletions data_add2.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,131 @@
    {
    "nodes": [
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime164040649",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal51121931R",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime164042156",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal86695964J",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime164043663",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal5023564K",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime164056952",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal621260409Y",
    "type": "nominal"
    },
    {
    "isSolved": true,
    "id": "http://ns.valcri.org/data/crimes#crime164061610",
    "type": "crime"
    },
    {
    "id": "http://ns.valcri.org/data/nominals#nominal22538418L",
    "type": "nominal"
    }
    ],
    "links": [
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime138640301",
    "target": "http://ns.valcri.org/data/crimes#crime164040649"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime164040649",
    "target": "http://ns.valcri.org/data/nominals#nominal51121931R"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime138640301",
    "target": "http://ns.valcri.org/data/crimes#crime164042156"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime164042156",
    "target": "http://ns.valcri.org/data/nominals#nominal86695964J"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime138640301",
    "target": "http://ns.valcri.org/data/crimes#crime164043663"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime164043663",
    "target": "http://ns.valcri.org/data/nominals#nominal5023564K"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime138640301",
    "target": "http://ns.valcri.org/data/crimes#crime164056952"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime164056952",
    "target": "http://ns.valcri.org/data/nominals#nominal621260409Y"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "crime",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime138640301",
    "target": "http://ns.valcri.org/data/crimes#crime164061610"
    },
    {
    "sourceType": "crime",
    "link": "similarity",
    "targetType": "nominal",
    "id": "link",
    "source": "http://ns.valcri.org/data/crimes#crime164061610",
    "target": "http://ns.valcri.org/data/nominals#nominal22538418L"
    }
    ]
    }
    12 changes: 6 additions & 6 deletions graph.js
    Original file line number Diff line number Diff line change
    @@ -148,12 +148,12 @@
    var dataLev2 = _this.datalev2();
    var data = _this.data();

    data.nodes = data.nodes.filter(function(n) {
    return n.level !== "level2"
    });
    data.links = data.links.filter(function(l) {
    return l.level !== "level2"
    });
    // data.nodes = data.nodes.filter(function(n) {
    // return n.level !== "level2"
    // });
    // data.links = data.links.filter(function(l) {
    // return l.level !== "level2"
    // });

    var i;
    for (i = 0; i < dataLev2.nodes.length; i++) {
    43 changes: 16 additions & 27 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -14,25 +14,29 @@
    var chart;
    var defs;
    var avatars = {};
    var id = "170135094";
    var id = "162033325";

    var custNodeDrawCallback = function(selection, d)
    {
    var def = defs[d.type]

    if(d.id == id) {
    avatar.draw(def.color1, def.color2, def.label, d.id, 20, false, selection);
    if(d.label == id) {
    var mark = d.type == 'crime' && !d.isSolved
    avatar.draw(def.color1, def.color2, def.label, d.id, 20, mark, selection);
    return;
    }
    else if(!avatars.hasOwnProperty(d.type))
    else if(!avatars.hasOwnProperty(d.type + d.isSolved))
    {
    avatars[d.type] = avatar.draw(def.color1, def.color2, def.label, d.id, 10, false, null);
    var mark = d.type == 'crime' && !d.isSolved
    avatars[d.type + d.isSolved] = avatar.draw(def.color1, def.color2, def.label, d.id, 10, mark, null);
    }

    var a = avatars[d.type]
    var a = avatars[d.type + d.isSolved]
    var i;
    for(i = 0; i < a.length; i++) {
    selection.appendChild(a[i].cloneNode(true));
    var savedAvatar = a[i].cloneNode(true)
    savedAvatar.setAttributeNS(null, "id", d.id);
    selection.appendChild(savedAvatar);
    }
    }

    @@ -43,7 +47,7 @@
    .attr("stroke", function(d) { return d.color || '#999'; })
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

    if(d.level == 'level2')
    if(d.link == 'similarity')
    line.attr("stroke-dasharray", "5 5");
    }

    @@ -61,25 +65,10 @@
    .call(chart.render);
    }

    d3.interval(function() {
    datalev2 = {},
    a = {
    "id": "a",
    "level": "level2",
    "type": "nominal"
    };
    b = {
    "id": "b",
    "level": "level2",
    "type": "crime"
    };
    nodes = [a, b],
    links = [{"level": "level2", source: b, target: "170135094"},
    {"level": "level2", source: a, target: b}];
    datalev2.nodes = nodes;
    datalev2.links = links;
    chart.datalev2(datalev2)
    }, 3000, d3.now());
    d3.timeout(function() {
    d3.json('data_add1.json', chart.datalev2);
    d3.json('data_add2.json', chart.datalev2);
    }, 3000);

    d3.json('data.json', display);
    };
  2. Patrick Seidler revised this gist Jul 27, 2017. 5 changed files with 1055 additions and 1 deletion.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -2,3 +2,4 @@
    =======

    Reusable Chart component for D3 - Using factories

    66 changes: 66 additions & 0 deletions avatar.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    function avatar() {
    }

    avatar.draw = function() {
    var args = Array.prototype.slice.call(arguments)
    var fontWeight = 'bold', textColour = '#ffffff';
    // TODO: CHECK RETURNS FALSE, WHY?
    // if (args[args.length - 1] instanceof SVGElement)
    var target = args.pop()
    var mark = args.pop()
    var radius = args.pop()
    var id = args.pop()
    var charCode = args.pop()
    var secColour = args.pop()
    var primColour = args.pop()

    var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
    text.setAttribute('class', 'avatar--text__main');
    text.setAttributeNS(null, "fill", textColour);
    text.setAttributeNS(null, "pointer-events", "auto");
    text.setAttributeNS(null, "id", id);
    text.setAttributeNS(null, "dy", '0.35em');
    text.setAttributeNS(null, "text-anchor", "middle");
    text.setAttributeNS(null, "font-weight", fontWeight);
    text.setAttributeNS(null, "font-size", radius - 2);

    text.innerHTML = charCode;

    var circle = document.createElementNS("http://www.w3.org/2000/svg",
    "circle");
    var inner;

    if (mark) {
    circle.setAttribute('class', 'avatar--circle__mark-stroke');
    circle.setAttributeNS(null, "stroke", secColour);
    circle.setAttributeNS(null, "r", radius - 1);
    circle.setAttributeNS(null, "stroke-width", 2);
    circle.setAttributeNS(null, "fill", "none");

    inner = document.createElementNS("http://www.w3.org/2000/svg",
    "circle");
    inner.setAttribute('class', 'avatar--circle__mark-main');
    inner.setAttributeNS(null, "r", radius - 3);
    inner.setAttributeNS(null, "stroke", "none");
    inner.setAttributeNS(null, "fill", primColour);
    inner.setAttributeNS(null, "id", id);
    if(target != null) target.appendChild(inner);
    } else {
    circle.setAttribute('class', 'avatar--circle__mark-main');
    circle.setAttributeNS(null, "r", radius);
    circle.setAttributeNS(null, "stroke", "none");
    circle.setAttributeNS(null, "fill", primColour);
    }

    circle.setAttributeNS(null, "id", id);

    if(target != null) {
    target.appendChild(circle);
    target.appendChild(text);
    return;
    }

    var a = new Array(circle, text);
    if(inner != null) a.unshift(inner);
    return a;
    };
    551 changes: 551 additions & 0 deletions d3v4-brush-lite.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,551 @@
    (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-drag'), require('d3-interpolate'), require('d3-selection'), require('d3-transition')) :
    typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-drag', 'd3-interpolate', 'd3-selection', 'd3-transition'], factory) :
    (factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3));
    }(this, (function (exports,d3Dispatch,d3Drag,d3Interpolate,d3Selection,d3Transition) { 'use strict';

    var constant = function(x) {
    return function() {
    return x;
    };
    };

    var BrushEvent = function(target, type, selection) {
    this.target = target;
    this.type = type;
    this.selection = selection;
    };

    function nopropagation() {
    d3Selection.event.stopImmediatePropagation();
    }

    var noevent = function() {
    d3Selection.event.preventDefault();
    d3Selection.event.stopImmediatePropagation();
    };

    var MODE_DRAG = {name: "drag"};
    var MODE_SPACE = {name: "space"};
    var MODE_HANDLE = {name: "handle"};
    var MODE_CENTER = {name: "center"};

    var X = {
    name: "x",
    handles: ["e", "w"].map(type),
    input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
    output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
    };

    var Y = {
    name: "y",
    handles: ["n", "s"].map(type),
    input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
    output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
    };

    var XY = {
    name: "xy",
    handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
    input: function(xy) { return xy; },
    output: function(xy) { return xy; }
    };

    var cursors = {
    overlay: "crosshair",
    selection: "move",
    n: "ns-resize",
    e: "ew-resize",
    s: "ns-resize",
    w: "ew-resize",
    nw: "nwse-resize",
    ne: "nesw-resize",
    se: "nwse-resize",
    sw: "nesw-resize"
    };

    var flipX = {
    e: "w",
    w: "e",
    nw: "ne",
    ne: "nw",
    se: "sw",
    sw: "se"
    };

    var flipY = {
    n: "s",
    s: "n",
    nw: "sw",
    ne: "se",
    se: "ne",
    sw: "nw"
    };

    var signsX = {
    overlay: +1,
    selection: +1,
    n: null,
    e: +1,
    s: null,
    w: -1,
    nw: -1,
    ne: +1,
    se: +1,
    sw: -1
    };

    var signsY = {
    overlay: +1,
    selection: +1,
    n: -1,
    e: null,
    s: +1,
    w: null,
    nw: -1,
    ne: -1,
    se: +1,
    sw: +1
    };

    function type(t) {
    return {type: t};
    }

    // Ignore right-click, since that should open the context menu.
    function defaultFilter() {
    return !d3Selection.event.button;
    }

    function defaultExtent() {
    var svg = this.ownerSVGElement || this;
    return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
    }

    // Like d3.local, but with the name “__brush” rather than auto-generated.
    function local(node) {
    while (!node.__brush) if (!(node = node.parentNode)) return;
    return node.__brush;
    }

    function empty(extent) {
    return extent[0][0] === extent[1][0]
    || extent[0][1] === extent[1][1];
    }

    function brushSelection(node) {
    var state = node.__brush;
    return state ? state.dim.output(state.selection) : null;
    }

    function brushX() {
    return brush$1(X);
    }

    function brushY() {
    return brush$1(Y);
    }

    var brush = function() {
    return brush$1(XY);
    };

    function brush$1(dim) {
    var extent = defaultExtent,
    filter = defaultFilter,
    listeners = d3Dispatch.dispatch(brush, "start", "brush", "end"),
    handleSize = 6,
    touchending;

    function brush(group) {

    var overlay = group
    .property("__brush", initialize)
    .selectAll(".overlay")
    .data([type("overlay")]);

    overlay.enter().append("rect")
    .attr("class", "overlay")
    .attr("pointer-events", "all")
    .attr("cursor", cursors.overlay)
    .merge(overlay)
    .each(function() {
    var extent = local(this).extent;
    d3Selection.select(this)
    .attr("x", extent[0][0])
    .attr("y", extent[0][1])
    .attr("width", extent[1][0] - extent[0][0])
    .attr("height", extent[1][1] - extent[0][1]);
    });

    group.selectAll(".selection")
    .data([type("selection")])
    .enter().append("rect")
    .attr("class", "selection")
    .attr("cursor", cursors.selection)
    .attr("fill", "#777")
    .attr("fill-opacity", 0.3)
    .attr("stroke", "#fff")
    .attr("shape-rendering", "crispEdges");

    var handle = group.selectAll(".handle")
    .data(dim.handles, function(d) { return d.type; });

    handle.exit().remove();

    handle.enter().append("rect")
    .attr("class", function(d) { return "handle handle--" + d.type; })
    .attr("cursor", function(d) { return cursors[d.type]; });

    group
    .each(redraw)
    .attr("fill", "none")
    .attr("pointer-events", "all")
    .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
    .on("mousedown.brush touchstart.brush", started);
    }

    brush.move = function(group, selection) {
    if (group.selection) {
    group
    .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
    .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
    .tween("brush", function() {
    var that = this,
    state = that.__brush,
    emit = emitter(that, arguments),
    selection0 = state.selection,
    selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
    i = d3Interpolate.interpolate(selection0, selection1);

    function tween(t) {
    state.selection = t === 1 && empty(selection1) ? null : i(t);
    redraw.call(that);
    emit.brush();
    }

    return selection0 && selection1 ? tween : tween(1);
    });
    } else {
    group
    .each(function() {
    var that = this,
    args = arguments,
    state = that.__brush,
    selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
    emit = emitter(that, args).beforestart();

    d3Transition.interrupt(that);
    state.selection = selection1 == null || empty(selection1) ? null : selection1;
    redraw.call(that);
    emit.start().brush().end();
    });
    }
    };

    function redraw() {
    var group = d3Selection.select(this),
    selection = local(this).selection;

    if (selection) {
    group.selectAll(".selection")
    .style("display", null)
    .attr("x", selection[0][0])
    .attr("y", selection[0][1])
    .attr("width", selection[1][0] - selection[0][0])
    .attr("height", selection[1][1] - selection[0][1]);

    group.selectAll(".handle")
    .style("display", null)
    .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
    .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
    .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
    .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
    }

    else {
    group.selectAll(".selection,.handle")
    .style("display", "none")
    .attr("x", null)
    .attr("y", null)
    .attr("width", null)
    .attr("height", null);
    }
    }

    function emitter(that, args) {
    return that.__brush.emitter || new Emitter(that, args);
    }

    function Emitter(that, args) {
    this.that = that;
    this.args = args;
    this.state = that.__brush;
    this.active = 0;
    }

    Emitter.prototype = {
    beforestart: function() {
    if (++this.active === 1) this.state.emitter = this, this.starting = true;
    return this;
    },
    start: function() {
    if (this.starting) this.starting = false, this.emit("start");
    return this;
    },
    brush: function() {
    this.emit("brush");
    return this;
    },
    end: function() {
    if (--this.active === 0) delete this.state.emitter, this.emit("end");
    return this;
    },
    emit: function(type) {
    d3Selection.customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
    }
    };

    function started() {
    if (d3Selection.event.touches) { if (d3Selection.event.changedTouches.length < d3Selection.event.touches.length) return noevent(); }
    else if (touchending) return;
    if (!filter.apply(this, arguments)) return;

    var that = this,
    type = d3Selection.event.target.__data__.type,
    mode = (d3Selection.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (d3Selection.event.altKey ? MODE_CENTER : MODE_HANDLE),
    signX = dim === Y ? null : signsX[type],
    signY = dim === X ? null : signsY[type],
    state = local(that),
    extent = state.extent,
    selection = state.selection,
    W = extent[0][0], w0, w1,
    N = extent[0][1], n0, n1,
    E = extent[1][0], e0, e1,
    S = extent[1][1], s0, s1,
    dx,
    dy,
    moving,
    lockX,
    lockY,
    point0 = d3Selection.mouse(that),
    point = point0,
    emit = emitter(that, arguments).beforestart();

    if (type === "overlay") {
    state.selection = selection = [
    [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
    [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
    ];
    } else {
    w0 = selection[0][0];
    n0 = selection[0][1];
    e0 = selection[1][0];
    s0 = selection[1][1];
    }

    w1 = w0;
    n1 = n0;
    e1 = e0;
    s1 = s0;

    var group = d3Selection.select(that)
    .attr("pointer-events", "none");

    var overlay = group.selectAll(".overlay")
    .attr("cursor", cursors[type]);

    if (d3Selection.event.touches) {
    group
    .on("touchmove.brush", moved, true)
    .on("touchend.brush touchcancel.brush", ended, true);
    } else {
    var view = d3Selection.select(d3Selection.event.view)
    .on("keydown.brush", keydowned, true)
    .on("keyup.brush", keyupped, true)
    .on("mousemove.brush", moved, true)
    .on("mouseup.brush", ended, true);

    d3Drag.dragDisable(d3Selection.event.view);
    }

    nopropagation();
    d3Transition.interrupt(that);
    redraw.call(that);
    emit.start();

    function moved() {
    var point1 = d3Selection.mouse(that);
    point = point1;
    moving = true;
    noevent();
    move();
    }

    function move() {
    var t;

    dx = point[0] - point0[0];
    dy = point[1] - point0[1];

    switch (mode) {
    case MODE_SPACE:
    case MODE_DRAG: {
    if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
    if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
    break;
    }
    case MODE_HANDLE: {
    if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
    else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
    if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
    else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
    break;
    }
    case MODE_CENTER: {
    if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
    if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
    break;
    }
    }

    if (e1 < w1) {
    signX *= -1;
    t = w0, w0 = e0, e0 = t;
    t = w1, w1 = e1, e1 = t;
    if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
    }

    if (s1 < n1) {
    signY *= -1;
    t = n0, n0 = s0, s0 = t;
    t = n1, n1 = s1, s1 = t;
    if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
    }

    if (state.selection) selection = state.selection; // May be set by brush.move!
    if (lockX) w1 = selection[0][0], e1 = selection[1][0];
    if (lockY) n1 = selection[0][1], s1 = selection[1][1];

    if (selection[0][0] !== w1
    || selection[0][1] !== n1
    || selection[1][0] !== e1
    || selection[1][1] !== s1) {
    state.selection = [[w1, n1], [e1, s1]];
    redraw.call(that);
    emit.brush();
    }
    }

    function ended() {
    nopropagation();
    if (d3Selection.event.touches) {
    if (d3Selection.event.touches.length) return;
    if (touchending) clearTimeout(touchending);
    touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
    group.on("touchmove.brush touchend.brush touchcancel.brush", null);
    } else {
    d3Drag.dragEnable(d3Selection.event.view, moving);
    view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
    }
    group.attr("pointer-events", "all");
    overlay.attr("cursor", cursors.overlay);
    if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
    if (empty(selection)) state.selection = null, redraw.call(that);
    emit.end();
    }

    function keydowned() {
    switch (d3Selection.event.keyCode) {
    case 18: { // ALT
    if (mode === MODE_HANDLE) {
    if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
    if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
    mode = MODE_CENTER;
    move();
    }
    break;
    }
    case 32: { // SPACE; takes priority over ALT
    if (mode === MODE_HANDLE || mode === MODE_CENTER) {
    if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
    if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
    mode = MODE_SPACE;
    overlay.attr("cursor", cursors.selection);
    move();
    }
    break;
    }
    default: return;
    }
    noevent();
    }

    function keyupped() {
    switch (d3Selection.event.keyCode) {
    case 18: { // ALT
    if (mode === MODE_CENTER) {
    if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
    if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
    mode = MODE_HANDLE;
    move();
    }
    break;
    }
    case 32: { // SPACE
    if (mode === MODE_SPACE) {
    if (d3Selection.event.altKey) {
    if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
    if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
    mode = MODE_CENTER;
    } else {
    if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
    if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
    mode = MODE_HANDLE;
    }
    overlay.attr("cursor", cursors[type]);
    move();
    }
    break;
    }
    default: return;
    }
    noevent();
    }
    }

    function initialize() {
    var state = this.__brush || {selection: null};
    state.extent = extent.apply(this, arguments);
    state.dim = dim;
    return state;
    }

    brush.extent = function(_) {
    return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
    };

    brush.filter = function(_) {
    return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), brush) : filter;
    };

    brush.handleSize = function(_) {
    return arguments.length ? (handleSize = +_, brush) : handleSize;
    };

    brush.on = function() {
    var value = listeners.on.apply(listeners, arguments);
    return value === listeners ? brush : value;
    };

    return brush;
    }

    exports.brush = brush;
    exports.brushX = brushX;
    exports.brushY = brushY;
    exports.brushSelection = brushSelection;

    Object.defineProperty(exports, '__esModule', { value: true });

    })));
    436 changes: 436 additions & 0 deletions graph.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,436 @@
    (function() {

    // ***************************************************
    // Globals
    // ***************************************************
    var gBrushHolder;
    var gBrush = null;
    var gDraw = null;
    var brushMode = false;
    var brushing = false;
    var shiftKey;
    var node, link, n, l;
    var brush = null;
    var d3;
    // ***************************************************
    // Defaults
    // ***************************************************
    /**
    * Define default variables here. Those are combined within
    * the incoming user options which would overwrite the
    * defaults.
    **/
    var defaults = {
    data: {},
    datalev2: {},
    custnodedraw: null,
    custlinkdraw: null
    };

    /**
    * Static initialisation
    **/
    window.EntityGraph = {
    instanceOf : function (d3version, options) {
    // Publish instance
    return new EntityGraph(d3version, options);
    }
    };

    // ***************************************************
    // Define Chart class and methods
    // ***************************************************
    function EntityGraph(d3version, options) {
    d3 = d3version
    this.options = extend({}, defaults, options != null ? options : {});
    makeAccessor.call(this, this.options)
    this.render = drawSelection.bind(this);
    }

    /**
    * Define the D3 callback to render graph within the specified
    * selection DOMs
    */
    function drawSelection(selection) {
    brush = d3.brush()
    .on("start", brushstarted)
    .on("brush", brushed)
    .on("end", brushended);

    d3.select('body').on('keydown', keydown);
    d3.select('body').on('keyup', keyup);

    _this = this;

    selection.each(function() {

    //TODO allow overwrite of width height
    // Width/Height are sized to the selection's node size
    var width = parseInt(d3.select(this).node().getBoundingClientRect().width, 10);
    var height = parseInt(d3.select(this).node().getBoundingClientRect().height, 10);

    // Retrieve local variables from class variables
    var data = _this.data();

    // Create base svg and add the data
    var svg = d3.select(this).selectAll("svg").data([ data ]);
    var gEnter = svg.enter().append('div').classed(
    'svg-container', true).append('svg')
    .attr("width", width)
    .attr("height", height)

    // Remove any previous graphs
    gEnter.selectAll('.g-main').remove();

    // Add our full zoomable graph group
    var gMain = gEnter.append('g')
    .classed('g-main', true);
    var zoom = d3.zoom().on('zoom', zoomed)
    gMain.call(zoom);

    // Background, catches clicks to reset node selection
    var rect = gMain.append('rect')
    .attr('width', width)
    .attr('height', height)
    .style('fill', 'white')
    .on('click', () => {

    node.selectAll('.node-el').each(function(d) {

    this.selected = false;
    this.previouslySelected = false;
    });
    node.selectAll('.node-el').classed("selected", false);
    });

    // Container to draw our graph in
    gDraw = gMain.append('g').attr("class", "drawContainer");

    // Brush container
    // The brush needs to go before the nodes so that it doesn't
    // get called when the mouse is over a node
    gBrushHolder = gDraw.append('g').attr("class", "brushHolder");
    gBrush = null;

    // Simulation forces
    simulation = d3.forceSimulation()
    .force("link", d3.forceLink()
    .id(function(d) { return d.id; })
    .distance(function(d) {
    return 10;
    })
    )
    .force("charge", d3.forceManyBody().strength(-120))
    .force("center", d3.forceCenter(width / 2, height / 2))
    .force("x", d3.forceX(width/2))
    .force("y", d3.forceY(height/2));

    _this.update(this);

    // ***************************************************
    // Update methods
    // Reacting automatically once the corresponding variable is set
    // ***************************************************
    _this.updateData = function() {
    update();
    };

    _this.updateDatalev2 = function() {
    _this.updateDataLevel2(this);
    };
    });
    }

    EntityGraph.prototype.updateDataLevel2 = function(selection)
    {
    _this = this;

    var dataLev2 = _this.datalev2();
    var data = _this.data();

    data.nodes = data.nodes.filter(function(n) {
    return n.level !== "level2"
    });
    data.links = data.links.filter(function(l) {
    return l.level !== "level2"
    });

    var i;
    for (i = 0; i < dataLev2.nodes.length; i++) {
    data.nodes.push(dataLev2.nodes[i]);
    }

    for (i = 0; i < dataLev2.links.length; i++) {
    data.links.push(dataLev2.links[i]);
    }

    _this.update(selection);

    simulation.alpha(1).restart();
    }

    /**
    * Draw the initial and update the existing graph with the full
    * current data set
    */
    EntityGraph.prototype.update = function(selection)
    {
    _this = this;

    // Retrieve local variables from class variables
    var data = _this.data();
    var custnodedraw = _this.custnodedraw();
    var custlinkdraw = _this.custlinkdraw();

    // Update data
    l = gDraw.selectAll(".link")
    .data(data.links, function(d) {return d.source + "," + d.target});
    n = gDraw.selectAll(".node").data(data.nodes, function(d) {return d.id})

    // Apply general update pattern
    exitLinks(l);
    enterLinks(l, custlinkdraw);
    exitNodes(n);
    enterNodes(n, custnodedraw);

    // Refernce to node and link selections
    link = gDraw.selectAll(".link");
    node = gDraw.selectAll(".node");

    // Feed simulation with current data
    simulation
    .nodes(data.nodes)
    .on("tick", ticked);

    simulation.force("link")
    .links(data.links);
    }

    /**
    * Defines how new nodes are drawn
    */
    function enterNodes(n, drawCallback) {
    n = n.enter().append("g")
    .attr("class", function(d){return "node"})
    .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

    n.each(function (d) {
    if(drawCallback) {
    drawCallback(this, d);
    }
    else {
    d3.select(this).append("circle")
    .attr("cx", 0)
    .attr("cy", 0)
    .attr("r", function(d) {return 10})
    .classed("node-el", true);
    }
    });

    n.selectAll('.avatar--circle__mark-main').classed("node-el", true);
    }

    /**
    * Defines how new links are drawn
    */
    function enterLinks(l, drawCallback) {
    l = l.enter()

    l.each(function(d) {
    if(drawCallback) {
    drawCallback(this, d);
    }
    else {
    d3.select(this).insert("line", ".node")
    .attr("class", "link")
    .attr("stroke", function(d) { return d.color || '#999'; })
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); });
    }
    });
    }

    /**
    * Removes nodes that have been removed using update id
    */
    function exitNodes(n) {
    n.exit().remove();
    }

    /**
    * Removes links that have been removed using update id
    */
    function exitLinks(l) {
    l.exit().remove();
    }

    /**
    * On zoom
    */
    function zoomed() {
    gDraw.attr("transform", d3.event.transform);
    }

    function brushstarted() {
    // keep track of whether we're actively brushing so that we
    // don't remove the brush on keyup in the middle of a selection
    brushing = true;

    node.selectAll('.node-el').each(function(d) {
    this.previouslySelected = shiftKey && this.selected;
    });
    }

    function brushed() {
    if (!d3.event.sourceEvent) return;
    if (!d3.event.selection) return;

    var extent = d3.event.selection;

    node.each(function(d){
    d3.select(this).select('.node-el').classed("selected", function(){
    return this.selected = this.previouslySelected ^
    (extent[0][0] <= d.x && d.x < extent[1][0]
    && extent[0][1] <= d.y && d.y < extent[1][1]);
    });

    });
    }

    function brushended() {
    if (!d3.event.sourceEvent) return;
    if (!d3.event.selection) return;
    if (!gBrush) return;

    gBrush.call(brush.move, null);

    if (!brushMode) {
    // the shift key has been release before we ended our brushing
    gBrush.remove();
    gBrush = null;
    }

    brushing = false;
    }

    function keydown() {
    shiftKey = d3.event.shiftKey;

    if (shiftKey) {
    // if we already have a brush, don't do anything
    if (gBrush)
    return;

    brushMode = true;

    if (!gBrush) {
    gBrush = gBrushHolder.append('g');
    gBrush.call(brush);
    }
    }
    }

    function ticked() {
    // update node and line positions at every step of
    // the force simulation
    link.attr("x1", function(d) { return d.source.x; })
    .attr("y1", function(d) { return d.source.y; })
    .attr("x2", function(d) { return d.target.x; })
    .attr("y2", function(d) { return d.target.y; });

    node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    }

    function keyup() {
    shiftKey = false;
    brushMode = false;

    if (!gBrush)
    return;

    if (!brushing) {
    // only remove the brush if we're not actively brushing
    // otherwise it'll be removed when the brushing ends
    gBrush.remove();
    gBrush = null;
    }
    }

    function dragstarted(d) {
    if (!d3.event.active) simulation.alphaTarget(0.9).restart();

    if (!d.selected && !shiftKey) {
    // if this node isn't selected, then we have to unselect every other node
    node.selectAll('.node-el').classed("selected", function(p) { return this.selected = this.previouslySelected = false; });
    }

    d3.select(this).select('.node-el').classed("selected", function(p) { this.previouslySelected = this.selected; return d.selected = true; });

    node.filter(function(d) { return d3.select(this).select('.node-el').classed('selected'); })
    .each(function(d) {
    d.fx = d.x;
    d.fy = d.y;
    })

    }

    function dragged(d) {
    node.filter(function(d) { return d3.select(this).select('.node-el').classed('selected'); })
    .each(function(d) {
    d.fx += d3.event.dx;
    d.fy += d3.event.dy;
    })
    }

    function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
    node.filter(function(d) { return d3.select(this).select('.node-el').classed('selected'); })
    .each(function(d) {
    d.fx = null;
    d.fy = null;
    })
    }

    // ***************************************************
    // Utility methods
    // ***************************************************

    function makeAccessor(properties) {
    var _this = this;

    for (var i in properties) {
    (function (i) {
    _this[i] = function (value) {
    if(value === null || value === undefined)
    {
    return properties[i];
    }
    properties[i] = value;
    updateFunc = ("update" + i.toCamelCase());
    if (typeof _this[updateFunc] === 'function') _this[updateFunc]();
    return _this;
    }
    })(i);
    }
    }

    String.prototype.toCamelCase = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
    }

    function extend() {
    for (var i = 1; i < arguments.length; i++) {
    for (var prop in arguments[i]) {
    if (arguments[i].hasOwnProperty(prop)) {
    arguments[0][prop] = arguments[i][prop];
    }
    }
    }
    return arguments[0];
    }

    })();
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -94,7 +94,7 @@
    </div>
    </div>

    <script src="d3_4_8_0.min.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="d3v4-brush-lite.js"></script>
    <script src="avatar.js"></script>
    <script src="graph.js"></script>
  3. Patrick Seidler revised this gist Jul 27, 2017. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -2,4 +2,3 @@
    =======

    Reusable Chart component for D3 - Using factories

  4. Patrick Seidler created this gist Jul 27, 2017.
    37 changes: 37 additions & 0 deletions .gitignore
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,37 @@
    # Compiled source #
    ###################
    *.com
    *.class
    *.dll
    *.exe
    *.o
    *.so

    # Packages #
    ############
    # it's better to unpack these files and commit the raw source
    # git has its own built in compression methods
    *.7z
    *.dmg
    *.gz
    *.iso
    *.jar
    *.rar
    *.tar
    *.zip

    # Logs and databases #
    ######################
    *.log
    *.sql
    *.sqlite

    # OS generated files #
    ######################
    .DS_Store
    .DS_Store?
    ._*
    .Spotlight-V100
    .Trashes
    ehthumbs.db
    Thumbs.db
    5 changes: 5 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    # Description
    =======

    Reusable Chart component for D3 - Using factories

    776 changes: 776 additions & 0 deletions data.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,776 @@
    {
    "defs": {
    "highlight": {
    "color1": "#22929E",
    "color2": "#22929E",
    "label": "H"
    },
    "nominal": {
    "color1": "#8DA0CB",
    "color2": "#FC8D62",
    "label": "N"
    },
    "crime": {
    "color1": "#66C2A5",
    "color2": "#FC8D62",
    "label": "CR"
    },
    "locationrecord": {
    "color1": "#D870AD",
    "color2": "#D870AD",
    "label": "L"
    },
    "comctrl": {
    "color1": "#EBC24F",
    "color2": "#FC8D62",
    "label": "CO"
    },
    "intel": {
    "color1": "#B2DF8A",
    "color2": "#FC8D62",
    "label": "I"
    },
    "cam": {
    "color1": "#9BA37E",
    "color2": "#FC8D62",
    "label": "CA"
    }
    },
    "nodes": [
    {
    "level": "lev1",
    "id": "170135094",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "151390617",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "181013990",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "246866328",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "248643355",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "247687095",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "199034696",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "237148781",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "169599424",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "171776080",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "249115457",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "244037963",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "247481321",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "241249876",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "165925084",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "240137299",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "240137162",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "197404396",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "231180787",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "245082862",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "169004159",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "195340354",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "DOE_PARK-CARSINGTON",
    "type": "locationrecord"
    },
    {
    "level": "lev1",
    "id": "247740388",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "237314688",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "156923636",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "246850984",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "233248939",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "171428100",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "247112380",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "244623638",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "23571299T",
    "type": "nominal"
    },
    {
    "level": "lev1",
    "id": "238573307",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "233312507",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "243422559",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "183278463",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "238492751",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "145384537",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "180971246",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "249641537",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "246709463",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "232703405",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "166652691",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "WELLGREEN_ROAD-CARSINGTON",
    "type": "locationrecord"
    },
    {
    "level": "lev1",
    "id": "205400264",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "234934587",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "169220208",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "245839513",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "230235761",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "249389320",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "185286609",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "239263239",
    "type": "crime"
    },
    {
    "level": "lev1",
    "id": "244928052",
    "type": "crime"
    }
    ],
    "links": [
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link0",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "205400264"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link1",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "169599424"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link2",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "232703405"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link3",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "245082862"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link4",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "246866328"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link5",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "195340354"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link6",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "246850984"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link7",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "233312507"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link8",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "145384537"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link9",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "249641537"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link10",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "246709463"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link11",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "244623638"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link12",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "249389320"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link13",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "197404396"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link14",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "185286609"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link15",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "199034696"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link16",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "170135094"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link17",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "243422559"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link18",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "233248939"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link19",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "169220208"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link20",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "166652691"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link21",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "165925084"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link22",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "230235761"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link23",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "240137162"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link24",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "244928052"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link25",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247481321"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link26",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "171428100"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link27",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "244037963"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link28",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "231180787"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link29",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "181013990"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link30",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "237148781"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link31",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247112380"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link32",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "241249876"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link33",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "169004159"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link34",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "171776080"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link35",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "249115457"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link36",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247687095"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link37",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "238573307"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link38",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "239263239"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link39",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "247740388"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link40",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "183278463"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link41",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "237314688"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link42",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "240137299"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link43",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "238492751"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link44",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "234934587"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link45",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "180971246"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link46",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "248643355"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link47",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "151390617"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link48",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "156923636"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "crime",
    "id": "link49",
    "source": "23571299T",
    "type": "http://example.org#inCrime",
    "target": "245839513"
    },
    {
    "sourceType": "crime",
    "level": "lev1",
    "targetType": "locationrecord",
    "id": "link50",
    "source": "170135094",
    "type": "http://example.org#hasLocation",
    "target": "DOE_PARK-CARSINGTON"
    },
    {
    "sourceType": "nominal",
    "level": "lev1",
    "targetType": "locationrecord",
    "id": "link51",
    "source": "23571299T",
    "type": "http://example.org#hasHome",
    "target": "WELLGREEN_ROAD-CARSINGTON"
    }
    ]
    }
    13 changes: 13 additions & 0 deletions graph.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    #vis {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    overflow-x: hidden;
    overflow-y: hidden;
    }

    .node .selected {
    stroke: black;
    }
    102 changes: 102 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Entity Graph</title>
    <meta name="description" content="Entity Graph">
    <meta name="author" content="Patrick Seidler">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="reset.css">
    <link rel="stylesheet" href="graph.css">

    <script type="text/javascript">
    window.onload = function() {
    var chart;
    var defs;
    var avatars = {};
    var id = "170135094";

    var custNodeDrawCallback = function(selection, d)
    {
    var def = defs[d.type]

    if(d.id == id) {
    avatar.draw(def.color1, def.color2, def.label, d.id, 20, false, selection);
    return;
    }
    else if(!avatars.hasOwnProperty(d.type))
    {
    avatars[d.type] = avatar.draw(def.color1, def.color2, def.label, d.id, 10, false, null);
    }

    var a = avatars[d.type]
    var i;
    for(i = 0; i < a.length; i++) {
    selection.appendChild(a[i].cloneNode(true));
    }
    }

    var custLinkDrawCallback = function(selection, d)
    {
    var line = d3.select(selection).insert("line", ".node");
    line.attr("class", "link")
    .attr("stroke", function(d) { return d.color || '#999'; })
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

    if(d.level == 'level2')
    line.attr("stroke-dasharray", "5 5");
    }

    function display(data) {
    defs = data.defs;
    chart = EntityGraph
    .instanceOf(d3)
    .data(data)
    .custnodedraw(custNodeDrawCallback)
    .custlinkdraw(custLinkDrawCallback);

    //Or like this
    //var graph = Chart.instanceOf( { width : 500 } );
    var svg = d3.select("#vis")
    .call(chart.render);
    }

    d3.interval(function() {
    datalev2 = {},
    a = {
    "id": "a",
    "level": "level2",
    "type": "nominal"
    };
    b = {
    "id": "b",
    "level": "level2",
    "type": "crime"
    };
    nodes = [a, b],
    links = [{"level": "level2", source: b, target: "170135094"},
    {"level": "level2", source: a, target: b}];
    datalev2.nodes = nodes;
    datalev2.links = links;
    chart.datalev2(datalev2)
    }, 3000, d3.now());

    d3.json('data.json', display);
    };

    </script>
    </head>
    <body>
    <div class="container">
    <div id="vis"></div>

    <div class="footer">
    </div>
    </div>

    <script src="d3_4_8_0.min.js"></script>
    <script src="d3v4-brush-lite.js"></script>
    <script src="avatar.js"></script>
    <script src="graph.js"></script>
    </body>
    </html>
    124 changes: 124 additions & 0 deletions reset.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    /* HTML5 ✰ Boilerplate
    * ==|== normalize ==========================================================
    */

    article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
    audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
    audio:not([controls]) { display: none; }
    [hidden] { display: none; }

    html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
    body { margin: 0; font-size: 13px; line-height: 1.231; }
    body, button, input, select, textarea { font-family: sans-serif; color: #222; }

    ::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; }
    ::selection { background: #fe57a1; color: #fff; text-shadow: none; }

    a { color: #00e; }
    a:visited { color: #551a8b; }
    a:hover { color: #06e; }
    a:focus { outline: thin dotted; }
    a:hover, a:active { outline: 0; }

    abbr[title] { border-bottom: 1px dotted; }
    b, strong { font-weight: bold; }
    blockquote { margin: 1em 40px; }
    dfn { font-style: italic; }
    hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
    ins { background: #ff9; color: #000; text-decoration: none; }
    mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
    pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 1em; }
    pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
    q { quotes: none; }
    q:before, q:after { content: ""; content: none; }
    small { font-size: 85%; }
    sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
    sup { top: -0.5em; }
    sub { bottom: -0.25em; }
    ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
    dd { margin: 0 0 0 40px; }
    nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
    img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
    svg:not(:root) { overflow: hidden; }
    figure { margin: 0; }

    form { margin: 0; }
    fieldset { border: 0; margin: 0; padding: 0; }
    label { cursor: pointer; }
    legend { border: 0; *margin-left: -7px; padding: 0; }
    button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
    button, input { line-height: normal; *overflow: visible; }
    table button, table input { *overflow: auto; }
    button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; }
    input[type="checkbox"], input[type="radio"] { box-sizing: border-box; }
    input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
    input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
    button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
    textarea { overflow: auto; vertical-align: top; resize: vertical; }
    input:valid, textarea:valid { }
    input:invalid, textarea:invalid { background-color: #f0dddd; }

    table { border-collapse: collapse; border-spacing: 0; }
    td { vertical-align: top; }


    /* ==|== primary styles =====================================================
    Author:
    ========================================================================== */
















    /* ==|== non-semantic helper classes ======================================== */
    .ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; }
    .ir br { display: none; }
    .hidden { display: none !important; visibility: hidden; }
    .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
    .visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
    .invisible { visibility: hidden; }
    .clearfix:before, .clearfix:after { content: ""; display: table; }
    .clearfix:after { clear: both; }
    .clearfix { zoom: 1; }


    /* ==|== media queries ====================================================== */

    @media only screen and (min-width: 480px) {


    }

    @media only screen and (min-width: 768px) {

    }



    /* ==|== print styles ======================================================= */

    @media print {
    * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
    a, a:visited { text-decoration: underline; }
    a[href]:after { content: " (" attr(href) ")"; }
    abbr[title]:after { content: " (" attr(title) ")"; }
    .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
    pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
    thead { display: table-header-group; }
    tr, img { page-break-inside: avoid; }
    img { max-width: 100% !important; }
    @page { margin: 0.5cm; }
    p, h2, h3 { orphans: 3; widows: 3; }
    h2, h3 { page-break-after: avoid; }
    }
  5. ps23 created this gist Jul 26, 2017.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    HELLO WORLD