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
Post a Comment