javascript - Using d3 to append colored circles based on data -


i have svg structure following:

<g class="labels"></g> 

and d3 code:

// svg d3 context var labels = svg.select('.labels');  ca = labels.append('g');  function resize() {     ca         .call(coloraxis) // instance of d3.svg.axis() using same data below         .selectall('text')             .remove();      ca         .selectall('.tick').select('circle')             .data(data)         .enter().append('circle')             .style('fill', function (datum) {                 return '#' + datum.hex;             })             .attr('r', '7.5'); } 

and structure ends looking this:

<g class="labels">     <!-- ca.call(coloraxis) -->     <g>         <g class="tick" transform="translate(0,14.285714285714285)" style="opacity: 1;">             <line x2="-6" y2="0"></line>         </g>         <!-- more of these... -->     </g>     <circle r="7.5" style="fill: rgb(44, 149, 210);"></circle>     <!-- many of these there ticks --> </g> 

and every time calls resize, adds more circles (which not want). want structure this:

<g class="labels">     <!-- ca.call(coloraxis) -->     <g>         <g class="tick" transform="translate(0,14.285714285714285)" style="opacity: 1;">             <line x2="-6" y2="0"></line>             <circle r="7.5" style="fill: rgb(44, 149, 210);"></circle>         </g>         <!-- more of these... -->     </g> </g> 

how fix d3 code achieve this? i've tried changing ca.selectall('.tick').select('circle') ca.selectall('.tick') , caused circles not appended @ all.

edit thought implied apparently not. resize() function called when dom resized , axis must adjusted accordingly fit content within space allotted. data not dynamic.

as mentioned in comments, solution offered @patrick great long it's understood axis must called , (hopefully) of tickmarks changed axis layout, between calls resize. reason existing circles not deleted each time routine called.

even if axis is called between updates, if number of tickmarks doesn't change - example if colour encoding of ticks changes - circles build every update.

using @patricks method use case...

 function onzoom(){     gxaxis.call(xaxis);     var update = gxaxis.selectall('.tick')       .data(x.ticks(xaxis.ticks()[0]))       .insert('circle', "line")       .attr('r', 7.5)       .attr('cy',function(){return 16 + i})       .style( "fill", function () {         return cr();       });     i++;     function cr(){       return d3.scale.category20().range()[math.round(math.random()*20)]     }   } 

working demo:

var margin = {      top: 20,      right: 20,      bottom: 30,      left: 30    },    width = 600 - margin.left - margin.right,    height = 50 - margin.top - margin.bottom;    var x = d3.scale.linear()    .range([0, width])    .domain([0, 100]),    zoom = d3.behavior.zoom()    .scaleextent([0.5, 3])    .on("zoom", onzoom);    var xaxis = d3.svg.axis()    .scale(x)    .orient("bottom")    .ticks(10);    var svg = d3.select("#viz").append("svg")    .attr("width", width + margin.left + margin.right)    .attr("height", height + margin.top + margin.bottom)    .call(zoom)    .append("g")    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"),    gxaxis = svg.append("g")    .attr("class", "x axis")    .attr("transform", "translate(0," + height + ")");  var = 0;    function onzoom() {    gxaxis.call(xaxis);    var update = gxaxis.selectall('.tick')      .data(x.ticks(xaxis.ticks()[0]))      .insert('circle', "line")      .attr('r', 7.5)      .attr('cy', function() {        return 16 +      })      .style("fill", function() {        return cr();      });    i++;      function cr() {      return d3.scale.category20().range()[math.round(math.random() * 20)]    }  }  onzoom();
svg {    outline: 1px solid red;    overflow: visible;  }  .domain,  .tick line {    fill: none;    stroke: black;  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>  <div id="viz">    <div>scroll update...</div>  </div>

it's not straight-forward solve however, , have add little bit more code... not much:

  function onzoom(){     gxaxis.call(xaxis);     var update = gxaxis       .datum(x.ticks(xaxis.ticks()[0]))       .selectall('.tick')       .data(function(d){         return d       })       .selectall('circle')       .data(function(d){         return [d]       });       update.enter().insert('circle', "line")       .attr('r', 7.5)       .attr('cy',function(){return 16 + i});     update.style( "fill", function (d, i, j) {       return cr() ;     })     i++;     function cr(){       return d3.scale.category20().range()[math.round(math.random()*20)]     }   } 

working demo same use case:

var margin = {      top: 20,      right: 20,      bottom: 30,      left: 30    },    width = 600 - margin.left - margin.right,    height = 50 - margin.top - margin.bottom;    var x = d3.scale.linear()    .range([0, width])    .domain([0, 100]),    zoom = d3.behavior.zoom()    .scaleextent([0.5, 3])    .on("zoom", onzoom);    var xaxis = d3.svg.axis()    .scale(x)    .orient("bottom")    .ticks(10);    var svg = d3.select("#viz").append("svg")    .attr("width", width + margin.left + margin.right)    .attr("height", height + margin.top + margin.bottom)    .call(zoom)    .append("g")    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"),    gxaxis = svg.append("g")    .attr("class", "x axis")    .attr("transform", "translate(0," + height + ")");  var = 0;    function onzoom() {    gxaxis.call(xaxis);    var update = gxaxis      .datum(x.ticks(xaxis.ticks()[0]))      .selectall('.tick')      .data(function(d) {        return d      })      .selectall('circle')      .data(function(d) {        return [d]      });    update.enter().insert('circle', "line")      .attr('r', 7.5)      .attr('cy', function() {        return 16 +      });    update.style("fill", function(d, i, j) {      return cr();    })    i++;      function cr() {      return d3.scale.category20().range()[math.round(math.random() * 20)]    }  }  onzoom();
svg {    outline: 1px solid red;    overflow: visible;  }  .domain,  .tick line {    fill: none;    stroke: black;  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>  <div id="viz">    <div>scroll update...</div>  </div>


Comments

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

html - jQuery UI Sortable - Remove placeholder after item is dropped -