javascript - D3: Spiral plot -


can me implementing spiral chart similar 1 using d3.js? https://en.wikipedia.org/wiki/file:condegram_spiral_plot.png

i've got basic spiral plot (a simple one) of not been able append bars plot based on timeline shown in image. i'm trying out few things (if see commented code).

https://jsfiddle.net/6bhdqqrf/1/

      var width = 400,       height = 430,       axes = 12,       tick_axis = 9,       start = 0,       end = 2.25;    var theta = function(r) {       return 2 * math.pi * r;   };    var angle = d3.scale.linear()       .domain([0, axes]).range([0, 360])    var r = d3.min([width, height]) / 2 - 40;   var r2 = r;    var radius = d3.scale.linear()       .domain([start, end])       .range([0, r]);    var svg = d3.select("#chart").append("svg")       .attr("width", width)       .attr("height", height)       .append("g")       .attr("transform", "translate(" + width / 2 + "," + (height / 2 + 8) + ")");    var points = d3.range(start, end + 0.001, (end - start) / 1000);    var spiral = d3.svg.line.radial()       .interpolate("cardinal")       .angle(theta)       .radius(radius);    var path = svg.selectall(".spiral")       .data([points])       .enter().append("path")       .attr("class", "spiral")       .attr("d", spiral)     var z = d3.scale.category20();    var circles = svg.selectall('.circle')       .data(points);    /*  circles.enter().append('circle')               .attr('r', 5)           .attr('transform', function(d) { return 'translate(' + d + ')'})           .style('fill', function(d) { return z(d); });        */    var circle = svg.append("circle")       .attr("r", 13)       .attr("transform", "translate(" + points[0] + ")");    var movingcircle = circle.transition().duration(4000)       .attrtween('transform', translatealongpath(path.node()))       //            .attr('cx', function(d) { return radius(d) * math.cos(theta(d))})       //        .attr('cy', function(d) { return radius(d) * math.sin(theta(d))})     function translatealongpath(path) {       var l = path.gettotallength();       return function(d, i, a) {           return function(t) {                var p = path.getpointatlength(t * l);               //console.log(p)               return "translate(" + p.x + "," + p.y + ")";           };       };   }    function pathxy(path) {       var l = path.gettotallength();       var start = 0;        /*  for(i=start; i<l; i++) {           var point = path.getpointatlength(i);           svg.append('rect').transition().duration(400).attr('transform', 'translate(' + point.x +','+point.y+')')           .attr('width', 10).attr('height', 30).style('fill', z);         }*/   }   pathxy(path.node());    /*var test = translatealongpath(path.node())()();   //console.log(test)   var bars = svg.selectall('.bar')       .data(points).enter().append('rect').transition().duration(2000)   //  .attrtween('transform', translatealongpath(path.node()))     .attr('class', 'bar')     .attr('width', 10)     .attr('height', 20)     .style('fill', function(d) { return z(d)});   */   var rect = svg.append('rect').attr('width', 10).attr('height', 10);   rect.transition().duration(3400)       .attrtween('transform', translatealongpath(path.node())); 

it'd great have few similar examples (i.e. spiral timeline plot).

thanks.

glad came , updated question, because interesting one. here's running minimal implementation. i've commented ok, let me know if have questions...

<!doctype html>  <html>    <head>    <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.js"></script>  </head>    <body>    <div id="chart"></div>    <script>      var width = 500,        height = 500,        start = 0,        end = 2.25,        numspirals = 4;        var theta = function(r) {        return numspirals * math.pi * r;      };        var r = d3.min([width, height]) / 2 - 40;        var radius = d3.scalelinear()        .domain([start, end])        .range([40, r]);        var svg = d3.select("#chart").append("svg")        .attr("width", width)        .attr("height", height)        .append("g")        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");        // create spiral, borrowed http://bl.ocks.org/syntagmatic/3543186      var points = d3.range(start, end + 0.001, (end - start) / 1000);        var spiral = d3.radialline()        .curve(d3.curvecardinal)        .angle(theta)        .radius(radius);        var path = svg.append("path")        .datum(points)        .attr("id", "spiral")        .attr("d", spiral)        .style("fill", "none")        .style("stroke", "steelblue");        // fudge data, 2 years of data starting today      var spirallength = path.node().gettotallength(),          n = 730,          barwidth = (spirallength / n) - 1;      var somedata = [];      (var = 0; < n; i++) {        var currentdate = new date();        currentdate.setdate(currentdate.getdate() + i);        somedata.push({          date: currentdate,          value: math.random()        });      }            // here's our time scale that'll run along spiral      var timescale = d3.scaletime()        .domain(d3.extent(somedata, function(d){          return d.date;        }))        .range([0, spirallength]);            // yscale bar height      var yscale = d3.scalelinear()        .domain([0, d3.max(somedata, function(d){          return d.value;        })])        .range([0, (r / numspirals) - 30]);        // append our rects      svg.selectall("rect")        .data(somedata)        .enter()        .append("rect")        .attr("x", function(d,i){                    // placement calculations          var lineper = timescale(d.date),              posonline = path.node().getpointatlength(lineper),              angleonline = path.node().getpointatlength(lineper - barwidth);                  d.lineper = lineper; // % distance on spiral          d.x = posonline.x; // x postion on spiral          d.y = posonline.y; // y position on spiral                    d.a = (math.atan2(angleonline.y, angleonline.x) * 180 / math.pi) - 90; //angle @ spiral position            return d.x;        })        .attr("y", function(d){          return d.y;        })        .attr("width", function(d){          return barwidth;        })        .attr("height", function(d){          return yscale(d.value);        })        .style("fill", "steelblue")        .style("stroke", "none")        .attr("transform", function(d){          return "rotate(" + d.a + "," + d.x  + "," + d.y + ")"; // rotate bar        });            // add date labels      var tf = d3.timeformat("%b %y"),          firstinmonth = {};      svg.selectall("text")        .data(somedata)        .enter()        .append("text")        .attr("dy", 10)        .style("text-anchor", "start")        .style("font", "10px arial")        .append("textpath")        // add first of each month        .filter(function(d){          var sd = tf(d.date);          if (!firstinmonth[sd]){            firstinmonth[sd] = 1;            return true;          }          return false;        })        .text(function(d){          return tf(d.date);        })        // place text along spiral        .attr("xlink:href", "#spiral")        .style("fill", "grey")        .attr("startoffset", function(d){          return ((d.lineper / spirallength) * 100) + "%";        })      </script>  </body>    </html>


Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -