My Technical Skills

In this example below you will see how to do a My Technical Skills with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by salihDemircan, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright salihDemircan ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>My Technical Skills</title>
  
  
  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  
<button onclick="showAll()">Repeat</button>
<p>Before</p>
<div id="skills" class="skills"></div>
<p>After</p>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.3/d3.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/salihDemircan/my-technical-skills-RZPKdz */

html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit; 
}

body {
    background-color:#eee;
}

p {
  padding: 6px 12px; 
  background: rgba(255,255,255,.5);
  font-size: 16px;
}

button {
  margin: 12px 0 0 12px;
  border: 0;
  background: #ddd;
  border: 1px solid #aaa;
  padding: 10px 20px;
  font-size: 1rem;
  z-index: 1000;
  cursor: pointer;
}

.skills {
  /* display: flex;
  justify-content: center; */
  /* space-around */
  display: block;
  text-align: center;
  transform-origin: center 0;
  margin-bottom: -48px;
}

.svg-wrapper {
  display: inline-block;
  margin: 0 auto 48px auto;
}

.svg-wrapper a {
  display: block;
  text-align: center;
  margin-top: 12px;
  color: #333;
  font-size: 11px;
  text-decoration: none;
}

@media (max-width: 1365px) { 
  .skills {
    transform: scale(.75);
  }
}

@media (max-width: 575px) { 
  .skills {
    transform: scale(.85);
  }
}


/*Downloaded from https://www.codeseek.co/salihDemircan/my-technical-skills-RZPKdz */
const skills = document.getElementById('skills')
const style = skills.currentStyle || window.getComputedStyle(skills);
const marginBottom = parseInt(style.marginBottom, 10)

function adjustSizes() {
  const div = document.getElementById('skills')
  const h1 = div.offsetHeight
  const h2 = div.getBoundingClientRect().height
  div.style.marginBottom = '-' + (Math.floor(Math.abs(h1 - h2)) + Math.abs(marginBottom) - 16) + 'px'
  window.requestAnimationFrame(adjustSizes)
}
window.requestAnimationFrame(adjustSizes)

function saveSVG(elm, id) {
  const svgData = encodeURI(document.getElementById(id).innerHTML)
  const dataURI = 'data:image/svg+xml; charset=utf8, ' + svgData
  elm.href = dataURI
  elm.download = id + '.svg'
  return true
}



const svgChart = {
  width: 360,
  height: 360,
  radius: 100,
  sectorWidth: .2,
  radScale: 55,
  sectorScale: 1,
  shorten: 1.33,
  index: {
    start: 0,
    increase: 0.2
  },
  class: 'chart',
  elements: [
     { id: 1, type: 'g', class: 'bars', transform: { translate: { x: 180, y: 194 } } },
     { id: 2, type: 'text', class: 'rating', transform: { translate: { x: 240, y: 262 } }, style: 'font: 11px "Open Sans", Arial; text-transform: uppercase; fill: #888;' },
     { id: 3, type: 'text', class: 'label', transform: { translate: { x: 290, y: 263 } }, style: 'font: 15px "Open Sans", Arial; text-transform: uppercase;' },
     { id: 4, type: 'text', class: 'title', transform: { translate: { x: 180, y: 32 } }, style: 'font: 28px "Open Sans", Arial; ' }
  ],
  borderColor: '#eee',
  _barColors: [ '#1F2F16', '#395B50', '#5A7684', '#92AFD7', '#C5D1EB' ],
  __barColors: [ '#6E0F0F', '#8A1F1F', '#AB4949', '#CE9494', '#E1BFBF' ],
  barColors: [ '#161E26', '#3B4249', '#4F7CAC', '#9EC5EF', '#C0D0E0' ]
}

const chartData = {
    'front-end': {
        title: 'Front-End Dev',
        entries: [
          { value: 95, label: 'HTML'},
          { value: 90, label: 'CSS / SCSS'},
          { value: 80, label: 'JS / DOM'},
          { value: 65, label: 'jQuery'},
          { value: 50, label: 'UX / UI'}
      ]
    },
    'back-end': {
        title: 'Back-End Dev',
        entries: [
        { value: 80, label: 'Node.js'},
        { value: 65, label: 'ASP Classic'},
        { value: 65, label: 'SQL'},
        { value: 50, label: 'PHP'},
        { value: 10, label: 'Go'}
      ]
    },
    'data-formats': {
        title: 'Data Formats',
        entries: [
        { value: 100, label: 'JSON'},
        { value: 80, label: 'YAML'},
        { value: 65, label: 'CSV'},
        { value: 65, label: 'TOML'},
        { value: 50, label: 'XML'}
      ]
    },
    'data-fetching-api': {
        title: 'API / Data Fetching',
        entries: [
        { value: 90, label: 'AJAX'},
        { value: 80, label: 'REST'},
        { value: 65, label: 'WebSocket'},
        { value: 35, label: 'RPC'},
        { value: 10, label: 'GraphQL'}
      ]
    }
};

function drawBarCircleChart(id) {
    const data = chartData[id].entries.sort((a, b) => {
      return a.value < b.value
    });
    const size = 100 * svgChart.shorten // data[0].value * svgChart.shorten
    const bars = d3.select('#' + id + ' ' + '.' + svgChart.elements.find(x => x.id === 1).class)
    const rating = d3.select('#' + id + ' ' + '.' + svgChart.elements.find(x => x.id === 2).class)
    const label = d3.select('#' + id + ' ' + '.' + svgChart.elements.find(x => x.id === 3).class)
    const title = d3.select('#' + id + ' ' + '.' + svgChart.elements.find(x => x.id === 4).class)
    
    title.text(chartData[id].title);
    
    var arc = d3.arc()
        .innerRadius((d, i) => { return ((svgChart.index.start + i * svgChart.index.increase) / svgChart.sectorScale) * svgChart.radius + svgChart.radScale })
        .outerRadius((d, i) =>{ return (((svgChart.index.start + i * svgChart.index.increase) / svgChart.sectorScale) + (svgChart.sectorWidth / svgChart.sectorScale)) * svgChart.radius + svgChart.radScale })
        .startAngle(Math.PI)
        .endAngle((d) => { return Math.PI + (d.value / size) * 2 * Math.PI })
        
    var path = bars.selectAll('path').data(data);

    path.enter().append("svg:path")
        .attr('fill', (d, i) => { return svgChart.barColors[i] })
        .attr('stroke', svgChart.borderColor)
        .transition()
        .ease(d3.easeElastic)
        .duration(2000)
        .delay((d, i) => { return i * 75 })
        .attrTween('d', arcTween)
  
    rating.selectAll('tspan')
        .data(data)
        .enter()
        .append('tspan')
        .attr('x', -50)
        .attr('y', (d, i) => { return i * 20 })
        .html((d, i) => {
          if (d.value === 100) {
            return 'Ninja'
          } else if (d.value >= 95) {
            return 'Expert'    
          } else if (d.value >= 80) {
            return 'Pro' // Advanced
          } else if (d.value >= 65) {
            return 'Good'
          } else if (d.value >= 50) {
            return 'OK' // Good Enough, Average
          } else if (d.value >= 35) {
            return 'Fair'
          } else if (d.value >= 10) {
            return 'Basic'
          }
          return ''
        })
  
    label.selectAll('tspan')
        .data(data)
        .enter()
        .append('tspan')
        .attr('x', -50)
        .attr('y', (d, i) => { return i * 20 })
        .html((d, i) => { return d.label })
  
    function arcTween(b, j) {
        var i = d3.interpolate({value: 0}, b)
        return function(t) {
            return arc(i(t), j)
        }
    }
}

function show(id) {
  if (document.getElementById(id)) {
    document.getElementById(id).outerHTML = ''
  }
  svgCreate(id, 'skills')
  setTimeout(() => {
      drawBarCircleChart(id)
  }, 10);
}

function svgCreate(id, targetElm) {
  const div = document.createElement('DIV')
  div.id = id
  div.className = 'svg-wrapper'
  // const scale = 1
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  svg.setAttribute('viewbox', '0 0 ' + svgChart.width + ' ' + svgChart.height)
  //svg.setAttribute('width', (svgChart.width * scale) + 'px')
  //svg.setAttribute('height', (svgChart.height * scale) + 'px')
  svg.setAttribute('width', svgChart.width + 'px')
  svg.setAttribute('height', svgChart.height + 'px')
  svg.setAttribute('class', svgChart.class)
  for (const elm of svgChart.elements) {
    //svg.appendChild(svgCreateElement(svg.namespaceURI, elm.type, elm.class, elm.transform, elm.style, scale))
    svg.appendChild(svgCreateElement(svg.namespaceURI, elm.type, elm.class, elm.transform, elm.style))
  }
  div.appendChild(svg)
  
  const a = document.createElement('A')
  a.href = 'javascript:void(0)'
  a.onclick = function() { return saveSVG(this, id) }
  a.innerHTML = 'Download SVG (Chrome only)'
  div.appendChild(a)
  
  if (!targetElm) {
    return document.body.appendChild(div)
  }
  return document.getElementById(targetElm).appendChild(div)
}

//function svgCreateElement(svgNS, elmType, elmClass, elmTransform, elmStyle, scale) {
function svgCreateElement(svgNS, elmType, elmClass, elmTransform, elmStyle) {
  const elm = document.createElementNS(svgNS,elmType)
  elm.setAttribute('class', elmClass)
  if (elmClass === 'title') {
    elm.setAttribute('text-anchor', 'middle')
  }
  if (elmTransform && elmTransform.translate) {
    //elm.setAttribute('transform', 'translate(' + elmTransform.translate.x * scale + ', ' + elmTransform.translate.y * scale + ')')
    elm.setAttribute('transform', 'translate(' + elmTransform.translate.x + ', ' + elmTransform.translate.y + ')')
  }
   if (elmStyle) {
    elm.setAttribute('style', elmStyle)
  }
  //const a = elm.getAttribute('transform')
  //elm.setAttribute('transform', a + ', scale(' + scale + ')')
  elm.setAttribute('transform', elm.getAttribute('transform'))
  return elm
}

function showAll() {
  show('front-end')
  show('back-end')
  show('data-formats')
  show('data-fetching-api')
}
showAll()

Comments