inspired inspired - 1 month ago 6
Javascript Question

Generating Circle Buttons w/ SVG

I'm generating SVG Paths to use as buttons to represent days in a month. My generator works properly. I feed it 28 and it generates the proper number of paths. The only issue is that I want my paths to start from 90 degrees so that my first generated path(button) will be at the top instead of on the right.

My current generator working here.

This is a visual:

enter image description here

HTML

<div class="column column-three">
<div class="dial-label">DAY</div>
<div class="full-circle" id="day"></div>
</div>


JS Generator Code

var textCircleRadius = 35
createDial('#day',31,'28');

function createDial(selection,numOfButtons,circleText){
var svg = d3.select(selection)
.append('svg')
.attr('viewBox', '0 0 110 110');

svg.selectAll('path')
.data(createDialPath(numOfButtons))
.enter()
.append('path')
.attr('d', function(d){
return d;
})
.attr('class','dial-button')
.attr('id', function(d,i){ return 'd' + i;})
.on('click',function(event){
console.log(this);
});

svg.append('circle')
.attr('cx',55)
.attr('cy',55)
.attr('r',textCircleRadius)
.attr('class','mid-circle');

svg.append('text')
.attr('x','50%')
.attr('y','50%')
.attr('class', 'mid-circle-text')
.attr('id','mid-circle-text')
.attr('dy', '.3em')
.html(circleText);

return svg;
}


I tried to workout some of the math to get it to generate differently and also tried to reorganize my array of paths that I create to change the generation order, but couldn't figure out a solution that would work dynamically for any number of paths.

DBS DBS
Answer

I may be misunderstanding, but simply removing 90 degrees from the createDialPath() should work.

afD = i*degrees - degrees - 90;
atD = i*degrees - 90;

See these changes in action here:

var textCircleRadius = 35
createDial('#day', 31, '28');

function createDial(selection, numOfButtons, circleText) {
  var svg = d3.select(selection)
    .append('svg')
    .attr('viewBox', '0 0 110 110');

  svg.selectAll('path')
    .data(createDialPath(numOfButtons))
    .enter()
    .append('path')
    .attr('d', function(d) {
      return d;
    })
    .attr('class', 'dial-button')
    .attr('id', function(d, i) {
      return 'd' + i;
    })
    .on('click', function(event) {
      console.log(this);
    });

  svg.append('circle')
    .attr('cx', 55)
    .attr('cy', 55)
    .attr('r', textCircleRadius)
    .attr('class', 'mid-circle');

  svg.append('text')
    .attr('x', '50%')
    .attr('y', '50%')
    .attr('class', 'mid-circle-text')
    .attr('id', 'mid-circle-text')
    .attr('dy', '.3em')
    .html(circleText);

  return svg;
}

function createDialPath(numOfSegments) {
  // defaults
  var degrees = 360 / numOfSegments,
    text = 35,
    r = 50,
    xC = 55,
    yC = 55,
    pathString = [];

  // dynamic values
  var afD,
    atD,
    afR,
    atR,
    xF,
    yF,
    xT,
    yT,
    d;
  for (var i = 1; i <= numOfSegments; i++) {
    afD = i * degrees - degrees - 90;
    atD = i * degrees - 90;
    afR = afD * (Math.PI / 180);
    atR = atD * (Math.PI / 180);
    xF = ((r * Math.cos(afR)) + xC).toFixed(2);
    yF = ((r * Math.sin(afR)) + yC).toFixed(2);
    xT = ((r * Math.cos(atR)) + xC).toFixed(2);
    yT = ((r * Math.sin(atR)) + yC).toFixed(2);
    d = ['M', xC, ',', yC, ' ', 'L', xF, ',', yF, ' ', 'A', r, ',', r, ' 0 0,1 ', xT, ',', yT, 'z'].join('');
    pathString.push(d);
  }
  return pathString;
}
.full-circle {
  /*background-color: #c06;*/
  height: 100px;
  -moz-border-radius: 50px;
  -webkit-border-radius: 50px;
  width: 100px;
  display: block;
  position: relative;
  margin: 6px auto;
}
.dial-label {
  text-align: center;
  color: #42BBAA;
  font-weight: 100;
}
span.dial-selection-label {
  color: #777777;
  text-transform: uppercase;
  margin-top: 30px;
  display: block;
  font-size: 22px;
  font-weight: 100;
  text-align: center;
}
path {
  stroke: white;
  stroke-width: 2px;
}
circle {
  fill: yellowgreen;
  stroke: black;
}
.dial-button {
  fill: #E7E6E6;
}
.dial-button.active-month {
  fill: #78AE06;
}
.dial-button.active-season {
  fill: #EEA124;
}
.mid-circle {
  fill: #FFFFFF;
  stroke: white;
  stroke-width: 2px;
}
.mid-circle-text {
  text-anchor: middle;
  stroke: #7A7A7A;
  font-size: 19px;
  /*stroke-width: .2px;*/
  font-weight: 100;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="column column-three">
  <div class="dial-label">DAY</div>
  <div class="full-circle" id="day"></div>
</div>

Comments