In week 3 ben ik met D3 aan de slag gegaan om verschillende grafiek types uit te testten bij de data die we hadden. Samen met Justus heb ik gezeten om meer uitleg over D3 te krijgen zodat ik hiermee op weg kon.

Hier uit zijn de volgende uitstralingen gekomen:

Experiment 1

Experiment 1

Dit eerste experiment is gebaseerd op de D3 code geschreven door Remco, De grafiek die hierboven staat is een scatterplot. Om te begrijpen wat er nou precies gebeurt heb ik de code van Remco geanalyseerd en zelf herschreven. Zo werd mij duidelijk dat er eigenlijk verschillende stappen gebeuren:

const svg = d3.select('#graph').append('svg')
  .attr('width', width)
  .attr('height', svgHeight)
const xScale = d3.scaleLinear().range([0 + margin.width, width - margin.width])
const yScale = d3.scaleLinear().range([0 + margin.height, svgHeight - margin.height - 65])
const nodes = data.nodes

  xScale.domain([d3.min(nodes, (d) => d.x), d3.max(nodes, (d) => d.x)])
  yScale.domain([d3.min(nodes, (d) => d.y), d3.max(nodes, (d) => d.y)])
const circle = svg
    .selectAll('circle')
    .data(nodes)
    .join(
      (enter) => {
        enter = enter.append('rect')
        return enter
      },
      (update) => update,
      (exit) => exit.remove()
    )
circle
    .attr('opacity', '0.2')
    .attr('class', (nodes) => nodes.label)
    // .attr('fill', '#2781e7b2')
    .attr('class', (nodes) => nodes.label)
    .attr('cx', (nodes) => xScale(nodes.x))
    .attr('cy', (nodes) => yScale(nodes.y))
    .attr('r', (nodes) => {
      if (nodes.label === 'person') {
        return 30
      } else {
        return 10
      }
    })
    .attr('id', (nodes) => {
      return 'node' + nodes.id
    })

Wat het gekke is in D3 is dat je een element toevoegt voordat je deze hebt gemaakt, het duurde even voordat ik deze omschakeling had gemaakt

Experiment 2

Experiment 2

Het tweede experiment dat ik deed met D3 was een force directed graph. Eerder had ik gekeken naar een force directed tree. Maar omdat hier een hierarchie van data nodig was gebaseerd op belangrijkste werkte dit niet. In onze data zat namelijk niet zo’n hierarchie. Bij de force directed graph wordt er door D3 X en Y waardes aan de data gehangen waarna er lijnen getrokken kunnen worden tussen de nodes.

const simulation = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(links).id(d => d.id).distance(200))
    .force('charge', d3.forceManyBody())
    .force('center', d3.forceCenter(width / 2, height / 2))

Ik wou deze grafiek manier gebruiken om de links tussen personen en items visueel weer te geven. Zoals op de bovenstaande afbeelding te zien is resulteerde dit in een enorme “haarbal” van data. In de grafiek was het wel mogelijk om nodes te verslepen en zo duidelijker te zien wel connecties deze had.

Het verslepen van een Node.

Het verslepen van een Node.

In de praktijk bleek (hoe gaaf die er ook uit ziet) dat deze grafiek type niet gebruiksvriendelijk was.

Experiment 3

Experiment 3

Vorige week had ik al geëxperimenteerd met een Goeey effect wat er voor zorgt dat elementen in elkaar overvloeien, eigenlijk een lavalamp effect. Omdat veel items en nodes verborgen werden met dit effect ben ik gaan kijken of dit anders kan.

Helaas is het mij verder niet gelukt om dit aan te passen, omdat je met een clipping mask werkt kan je niet het gewenste effect creëren en alles zichtbaar op het scherm hebben. Wel heb ik weer meer geleerd over D3 met dit experiment, zo ook hoe enter, update en exit werken.