Creating a temporal range time-series spiral plot

后端 未结 3 606
猫巷女王i
猫巷女王i 2020-12-29 09:33

Similarly to this question, I\'m interested in creating time series spirals. The solution doesn\'t necessarily have to be implemented in R or using ggplot, but it seems the

3条回答
  •  死守一世寂寞
    2020-12-29 10:07

    This could be achieved relatively straightforwardly with d3. I'll use your data to create a rough template of one basic possible approach. Here's what the result of this approach might look like:

    The key ingredient is d3's radial line component that lets us define a line by plotting angle and radius (here's a recent answer showing another spiral graph, that answer started me down the path on this answer).

    All we need to do is scale angle and radius to be able to use this effectively (for which we need the first time and last time in the dataset):

    var angle = d3.scaleTime()
      .domain([start,end])
      .range([0,Math.PI * 2 * numberWeeks])
    
    var radius = d3.scaleTime()
      .domain([start,end])
      .range([minInnerRadius,maxOuterRadius])
    

    And from there we can create a spiral quite easily, we sample some dates throughout the interval and then pass them to the radial line function:

    var spiral = d3.radialLine()
        .curve(d3.curveCardinal)
        .angle(angle)
        .radius(radius);
    

    Here's a quick demonstration of just the spiral covering your time period. I'm assuming a base familiarity with d3 for this answer, so have not touched on a few parts of the code.

    Once we have that, it's just a matter of adding sections from the data. The most simple way would be to plainly draw a stroke with some width and color it appropriately. This requires the same as above, but rather than sampling points from the start and end times of the dataset, we just need the start and end times of each datum:

        // append segments on spiral:  
        var segments = g.selectAll()
          .data(data)
          .enter()
          .append("path")
          .attr("d", function(d) {
            return /* sample points and feed to spiral function here */;
          })
          .style("stroke-width", /* appropriate width here */ )
          .style("stroke",function(d) { return /* color logic here */ })
    

    This might look something like this (with data mouseover).

    This is just a proof of concept, if you were looking for more control and a nicer look, you could create a polygonal path for each data entry and use both fill & stroke. As is, you'll have to make do with layering strokes to get borders if desired and svg manipulations like line capping options.

    Also, as it's d3, and longer timespans may be hard to show all at once, you could show less time but rotate the spiral so that it animates through your time span, dropping off events at the end and creating them in the origin. The actual chart might need to be canvas for this to happen smoothly depending on number of nodes, but to convert to canvas is relatively trivial in this case.


    For the sake of filling out the visualization a little with a legend and day labels, this is what I have.

提交回复
热议问题