Week 3

Detailed description about my work during the third week

Notes from logbook

This week I continued working on the D3 application of our app, I was able to also display the data in a canvas instead of an svg. So if the possibility arises where the svg fails I now know how to implement a canvas. Still wasn't able to make the connecting links of the items and persons. I also was able to make the play/pause button for the automatic steps. Next up on the list is to make an step counter so people can see on which step you are. On thursday I worked some more on the wiki of this project. I wrote about the D3 library and the API Marcio made, after that we had a meeting with Yuri which was a brainstorm session about what visualisations we can use to properly display the data.

Logbookarrow-up-right

Deep dive of this week's work

So because it is possible that an SVG can become too large to work with, and it will slow down your browser, I had a look at displaying the data in a canvas. The advantage of displaying the data in a canvas is that you will only create one HTML element instead of the possibility of having thousands of different lines and circles in the SVG group that would result in a different HTML element for each node and link.

The code for that looked like this

const width = window.innerWidth
const height = window.innerHeight
const margin = {width: (0.1 * width), height:(0.1 * height)}


d3.select('#graph')
  .append('canvas')
  .attr('width', width)
  .attr('height', height)

const canvas = d3.select('canvas')
const ctx = canvas.node().getContext('2d')

const detachedContainer = document.createElement('custom')
const dataContainer = d3.select(detachedContainer)

const xScale = d3.scaleLinear().range([0 + margin.width, width - margin.width])
const yScale = d3.scaleLinear().range([0 + margin.height, height - margin.height])

const update =  async (data) => {
  console.log(data)
  xScale.domain([d3.min(data.nodes, (d) => d.x), d3.max(data.nodes, (d) => d.x)])
  yScale.domain([d3.min(data.nodes, (d) => d.y), d3.max(data.nodes, (d) => d.y)])

  ctx.clearRect(0, 0, canvas.attr('width'), canvas.attr('height'))

  await data.nodes.forEach(drawNode)
  await data.links.forEach(drawLink)
}

const drawNode = async (d) => {
  const x = xScale(d.x)
  const y = yScale(d.y)
  const color = (label) => {
    if (label === 'person'){
      return '#348b90b0'
    } else {
      return '#dc143cbe'
    }
  }
  const r = (label) => {
    if (label === 'person'){
      return 15
    } else {
      return 5
    }
  }

  ctx.moveTo(x,y)
  ctx.beginPath()
  ctx.arc(x,y, r(d.label), 0, Math.PI*2)
  ctx.fillStyle = color(d.label)
  ctx.fill()
}

In the end, we didn't end up using it because all the research that happened between my teammates and me was with SVGs. Therefore, rewriting it all to be applicable in a canvas would take too much time. Because writing the function so that it draws the data in the canvas is different to making an SVG.

Last updated