How to draw such a circle on svg, so that its orange color can be easily changed from 0 to 100%? I tried on css like that, but not a single solution came up with something, but in Svg I am a layman

enter image description here

  • If you were a layman in svg, you could do this task. - DogeDev
  • four
    @DogeDev not to be confused with the profane and the pro - KAGG Design
  • Gradient need? The question about him does not say, but in the picture he is. - Qwertiy
  • Yes, I only get 2 lines, one gradient from blue to blue, the other from yellow to orange - YourDeveloper
  • Progress is made like this - stroke-dasharray: 314px + stroke-dashoffset: 314-(percent*314)/100 + 'px' , where 314 is the диаметр*пи . But with such a fill more difficult - Artem Gorlachev

3 answers 3

Such is the crutch option. Change the stroke-dashoffset from 0 (full orange circle) to 564 (full blue). I have not mastered the option with interest, maybe it can be done that way.

Code on codepen

  .circle { cx: 60px; cy: 60px; r: 50px; fill: #fff; stroke: url(#linear-gradient); stroke-width: 4px; } .circle2 { cx: 61px; cy: 60px; r: 50px; fill: transparent; stroke: orange; stroke-width: 4px; stroke-dasharray: 564px; stroke-dashoffset: 450px; transform: rotate(-90deg) translateX(-121px); } 
  <svg> <linearGradient id="linear-gradient"> <stop offset="0%" stop-color="blue"/> <stop offset="100%" stop-color="aliceblue"/> </linearGradient> <circle class="circle"></circle> <circle class="circle2"></circle> </svg> 

    Perhaps interested in such a decision ...
    there is such a library D3JS (Data-Driven Documents)
    it allows you to realize beautiful things, including your task
    extending SVG features:

     <!DOCTYPE html> <meta charset="utf-8"> <style> .percent-score { font: 10px sans-serif; line-height: 1; font-weight: bold; font-size: 4em; } </style> <body> <svg width="900" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // оределяем рабочую область и устанавливаем начало координат в ее центр var svg = d3.select("svg"), width = svg.attr("width"), height = svg.attr("height"), g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var radius = d3.min([width, height]) / 2; var arc = d3.arc() .innerRadius(radius - 120) .outerRadius(radius - 80) .startAngle(function(d) { return d; }) .endAngle(function(d) { return d + dblpi / n * 1.2; }); var percent = i = 0; var dblpi = 2 * Math.PI; var n = 300; //плавность цвета (разрешение) g.selectAll("path") .data(d3.range(0, dblpi, dblpi / n)) .enter() .append("path") .attr("d", arc) .attr("id", "sector"); g.append("text") .attr("class", "percent-score") .attr("dy", ".35em") // выравниваем текст по центру диаграммы .attr("text-anchor", "middle") .attr("id", "percent-text") .text(percent + "%"); (function tick() { i = (i < n) ? i + 1 : 0; percent = (i / n * 100) | 0; // целое число % var color = d3.scaleLinear() .domain([0, i - 1, i, n]) .range(["yellow", "orange", "blue", "lightblue"]) .interpolate(d3.interpolateRgb) d3.select("#percent-text") .text(percent + "%"); d3.selectAll("#sector") .style("fill", function(d, i) { return color(i); }); setTimeout(tick, 30000 / n); })(); </script> 

    and static option:

     <!DOCTYPE html> <meta charset="utf-8"> <style> .percent-score { font: 10px sans-serif; line-height: 1; font-weight: bold; font-size: 4em; } </style> <body> <svg width="900" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // оределяем рабочую область и устанавливаем начало координат в ее центр var svg = d3.select("svg"), width = svg.attr("width"), height = svg.attr("height"), g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var radius = d3.min([width, height]) / 2; var arc = d3.arc() .innerRadius(radius - 120) .outerRadius(radius - 80) .startAngle(function(d) { return d; }) .endAngle(function(d) { return d + dblpi / n * 1.2; }); // 1.2 это чтоб артефакты на переходах перекрыть var n = 300; //плавность цвета (разрешение) var percent = 25; // процент жёлтооранжевого сектора var edge = n / 100 * percent; var dblpi = 2 * Math.PI; var color = d3.scaleLinear() .domain([0, edge - 1, edge, n]) .range(["yellow", "orange", "blue", "lightblue"]) .interpolate(d3.interpolateRgb) g.selectAll("path") .data(d3.range(0, dblpi, dblpi / n)) .enter() .append("path") .attr("d", arc) .style("fill", function(d, i) { return color(i); }); g.append("text") .attr("class", "percent-score") .attr("dy", ".35em") // выравниваем текст по центру диаграммы .attr("text-anchor", "middle") .text(percent + "%"); </script> 

    but without D3 complexity with a nonlinear gradient (along the circumference)

     <!DOCTYPE html> <svg width="270" height="270"> <defs> <linearGradient id="hgrad" y2="100%" > <stop offset="0%" style="stop-color:rgb(0,255,255)" /> <stop offset="100%" style="stop-color:rgb(0,0,255)" /> </linearGradient> <linearGradient id="lgrad" y1="100%" > <stop offset="0%" style="stop-color:rgb(245,0,0)" /> <stop offset="100%" style="stop-color:rgb(255,242,61)" /> </linearGradient> </defs> <g fill="none"> <circle r="100" cx="135" cy="135" stroke-width= "30" stroke-dasharray="471 157" stroke="url(#hgrad)"/> <!-- 75% 2*Math.Pi*r*0,75 = 471 --> <circle r="100" cx="135" cy="135" transform="rotate(-90 135 135)" stroke-width= "30" stroke-dasharray="157 471" stroke="url(#lgrad)"/> <!-- 25% 2*Math.Pi*r*0,25 = 157 --> </g> </svg> 

    any ideas? although the author already had enough of the previous 2 answers, although the gradient is clearly not resolved.

    Update 1:

    Above there were examples with a constant size of sectors of a chart, only their color changed and this is not always good, here’s another option with variable sector sizes (their number in the example is the same depending on the resolution); separately ie does not depend on the amount of data and the model of the pie chart itself now calculates D3 through the pie shape generator Pie.

     - <!DOCTYPE html> <meta charset="utf-8"> <style> .percent-score { font: 10px sans-serif; line-height: 1; font-weight: bold; font-size: 4em; } </style> <body> <svg width="900" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // оределяем рабочую область и устанавливаем начало координат в ее центр var svg = d3.select("svg"), width = svg.attr("width"), height = svg.attr("height"), g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var radius = d3.min([width, height]) / 2; var percent, ticknum; var indata = 200; // шкала данных от 0 до indata var gradient = 50; //плавность цвета (разрешение) // вычисление цветов секторов в соответствии с разрешением var color = d3.scaleLinear() .domain([0, gradient - 1, gradient, 2 * gradient]) .range(["yellow", "orange", "blue", "lightblue"]) .interpolate(d3.interpolateRgb); // вычисление размеров секторов var pie = d3.pie() .sort(null); var arc = d3.arc(); // инициализация диаграммы и установка цветов секторам var path = g.datum(d3.range(gradient * 2)).selectAll("path") .data(pie) .enter() .append("path") .attr("d", arc.innerRadius(radius - 120).outerRadius(radius - 80)) .style("fill", function(d, i) { return color(i); }); g.append("text") .attr("class", "percent-score") .attr("dy", ".35em") // выравниваем текст по центру диаграммы .attr("text-anchor", "middle") .attr("id", "percent-text"); (function tick() { ticknum = (ticknum < indata) ? ticknum + 1 : 0; percent = (ticknum / indata * 100) | 0; // получаем целое число % // определяем коэффициент для расчета размера сектора каждой из 2-х частей диаграммы // если текущий сектор меньше gradient то размер сектора увеличивается // (это увеличивающаяся половина секторов диаграммы) иначе уменьшается var sectorsize = d3.scaleThreshold() .domain([gradient]) .range([ticknum / gradient, (indata - ticknum) / gradient]); // расчет модели диаграммы pie.value(function(d) { return sectorsize(d); }); path.data(pie) // перерисовка секторов и поправка для конечной границы сектора - убираем артефакты .attr("d", arc.endAngle(function(d) { return d.endAngle + .01; })); d3.select("#percent-text") .text(percent + "%"); setTimeout(tick, 30000 / indata); })(); </script> 

    By the way, a similar question was raised here.

      If you need a static picture, without a dynamic change of the orange circle, then I would do this:

      1. Draw 2 circles with circlarc.svg - first full circle, then a small part. 2. Add a gradient to each (for example, angryTools ).

      it was easy to change from 0 to 100%

      It took me less than a minute.

       <svg fill="none" viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg"> <defs> <linearGradient id="lgrad" x1="0%" y1="53%" x2="100%" y2="47%" > <stop offset="0%" style="stop-color:rgb(255,242,61);stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(245,0,0);stop-opacity:1" /> </linearGradient> </defs> <defs> <linearGradient id="bluesky" x1="0%" y1="90%" x2="100%" y2="10%" > <stop offset="0%" style="stop-color:rgb(0,255,255);stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" /> </linearGradient> </defs> <path d="M 454 75 C 509.23 75 554 119.77 554 175 L 554 175 C 554 230.23 509.23 275 454 275 L 454 275 C 398.77 275 354 230.23 354 175 L 354 175 C 354 119.77 398.77 75 454 75 L 454 95 C 409.82 95 374 130.82 374 175 L 374 175 C 374 219.18 409.82 255 454 255 L 454 255 C 498.18 255 534 219.18 534 175 L 534 175 C 534 130.82 498.18 95 454 95 Z" fill="url(#bluesky)"/> <path d="M 454 75 C 509.23 75 554 119.77 554 175 L 534 175 C 534 130.82 498.18 95 454 95 Z" fill="url(#lgrad)"/> </svg> 

      • Pay attention to the gradient, I suppose it should be along the circumference - Akubik
      • @eclipseeer, thanks for the answer, and what did you draw through? - YourDeveloper
      • one
        @YourDeveloper a couple of months ago I made an online svg-circles drawing app - eclipseeer.imtqy.com/circlarc.svg/ . Enter the start / end path, the radius and get the ready path - eclipseeer
      • @eclipseeer Thank you so much! Can you give me any feedback on this issue ? .stackoverflow.com /questions/ 732413 / ? - YourDeveloper