キャンバス上の丸いグラフ

ご挨拶!



最近では、1つのプロジェクトで、パーセンテージを丸いグラフ(?)で表示する必要がありました。 そしていつものように、私はインターネット上で既製のソリューションを探し始めましたが、価値のあるものを見つけることができませんでした(おそらく、この要素が正しく呼び出される方法を正確に知らないためです)。 必要なものは多かれ少なかれKnobライブラリで見つかりましが、グラフの値を変更する必要がないため、その機能は冗長であることが判明しました。これに加えて、ライブラリにはバグがありました。 その結果、別の自転車を作らなければなりませんでした。



画像



最初にcssの方向を見ました。まあ、自分で判断してください-border-radiusで円を描くと、border-colorが何パーセントかを示します...もちろん、これは0%、25%、50%、75%、100%に当てはまります。



html:

<div class="dial procent0"><p>0%</p></div> <div class="dial procent25"><p>25%</p></div> <div class="dial procent50"><p>50%</p></div> <div class="dial procent75"><p>75%</p></div> <div class="dial procent100"><p>100%</p></div>
      
      





scss:

 .dial { width: 80px; height: 80px; font-size: 20px; text-align: center; line-height: 80px; border: 6px solid #262832; border-radius: 100%; margin: 20px; display: inline-block; transform: rotate(-45deg); p { margin: 0; transform: rotate(45deg); } &.procent25 { border-right-color: #689f38; } &.procent50 { border-right-color: #689f38; border-bottom-color: #689f38; } &.procent75 { border-right-color: #689f38; border-bottom-color: #689f38; border-left-color: #689f38; } &.procent100 { border-color: #689f38; } }
      
      





jsfiddle



このような議論を続ければ、疑似要素を使用して、ある円を別の円の上に描くことができます。 つまり、33%を表示する必要がある場合は、それぞれ25%の2つの円を描画し、33%の境界線が塗りつぶされるように2番目の円を回転します。これには、擬似要素が回転する角度を計算するだけです

3.690







html:

 <div class="dial"><p>33%</p></div>
      
      





scss:

 .dial { width: 80px; height: 80px; font-size: 20px; text-align: center; line-height: 80px; border: 6px solid #262832; border-radius: 100%; margin: 20px; display: inline-block; transform: rotate(-45deg); border-right-color: #1390d4; p { margin: 0; transform: rotate(45deg); } &::before { content: ''; display: block; position: absolute; width: 80px; height: 80px; border-radius: 100%; border: 6px solid transparent; border-right-color:#1390d4; margin: -6px -6px; transform: rotate(28.8deg); } }
      
      





jsfiddle



もちろん、51%以上のグラフを表示する必要がある場合は、境界の下部を塗りつぶす必要があります。 私のグラフの割合は静的ではなく、各グラフのスタイルを描くことは、少し間違っていますが、小数値が可能です...そして、DOMの外にあるためJavaの擬似要素へのアクセスはありませんが、JavaScriptが必要です-treesおよび単純なHTML要素としてアクセスできません。 もちろん、前に::をspanに置き換えてねじることができます...しかし、JavaScriptを使用する必要がある場合は、キャンバスにグラフを描画できます。特に、キャンバスには円を描く特別なアーク関数があるためです。



上記で書いたすべては、私の考えの経過を示すためだけのものです



円を描く:



 var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.beginPath(); ctx.arc(100,75,50,0,2*Math.PI); ctx.stroke();
      
      





画像

context.arc(x、y、r、sAngle、eAngle、反時計回り);



xyを犠牲にして、すべてが明確で、 r (半径)も問題を提起しません。オプションの反時計回りオプションは、円を描く方向を示します。デフォルトではfalse =時計回り、true =反時計回りです。



sAngleeAngleはラジアン単位の円の始点と終点です。gifでラジアンがどのようなものであるかはより明確です。

画像






関心をラジアンに変換するには、次の式を使用する必要があります。

=2π/100









実際、グラフを描くために必要なのはこれだけです。



html:

 <div class="dial blue" data-width="180" data-lineWidth="41">66.233467</div>
      
      





scss:

 .dial { border-color: #22262f; color: #689F38; display: inline-block; text-align: left; p { text-align:center; font-weight: bold; color: #fff; white-space: nowrap; position: relative; overflow: hidden; z-index: 1; margin: 0; } canvas { position: absolute; } }
      
      





JavaScript + jQuery:

 $(function(){ //     class="dial" var dials = $(".dial"); //   .dial    canvas  . for (i=0; i < dials.length; i++){ var width = (typeof $(dials[i]).attr("data-width") != 'undefined') ? Math.round($(dials[i]).attr("data-width")) : 80; var procent = (Number($(dials[i]).html()) > 0 && Number($(dials[i]).html()) < 100) ? Math.round(Number($(dials[i]).html()) * 10)/10 : 0; var lineWidth = (typeof $(dials[i]).attr("data-lineWidth") != 'undefined') ? Number($(dials[i]).attr("data-lineWidth")) : width / 10; if(lineWidth >= width) lineWidth = width+1; var size = width+lineWidth; var lineRound = (typeof $(dials[i]).attr("data-lineRound") != 'undefined') ? true : false; var borderColor = $(dials[i]).css("border-color"); var color = $(dials[i]).css("color"); //   .dial    data-width="80" //             border $(dials[i]).css({"width": size + 'px', "height": size + 'px', "font-size": Math.floor((width-lineWidth) / 4) + 'px'}); //  canvas      . $(dials[i]).html('<canvas id="dial' + i + '" width="' + size + '" height="' + size + '"></canvas><p>' + procent + '%</p>'); //     $("p", dials[i]).css({"line-height": size + 'px'}); var canvas = document.getElementById("dial" + i); var context = canvas.getContext("2d"); //     var radian = 2*Math.PI*procent/100; //     context.arc(width/2+lineWidth/2, width/2+lineWidth/2, width/2, 0, 2*Math.PI, false); context.lineWidth = lineWidth; context.strokeStyle = borderColor; context.stroke(); context.beginPath(); //     context.arc(width/2+lineWidth/2, width/2+lineWidth/2, width/2, 1.5 * Math.PI, radian+1.5 * Math.PI, false); context.strokeStyle = color; //        data-lineRound if (lineRound == true && lineWidth < width) context.lineCap = "round"; context.stroke(); } });
      
      





丸いグラフ(?)を追加するには、ページに追加する必要があります。



 <div class="dial"> (float)</div>
      
      





属性として追加できます:



データ幅 -直径(デフォルト80)

data-lineWidth-ライン幅(デフォルトでは直径の1/10)

*グラフのサイズはdata-width + data-lineWidthです

data-lineRound-セグメントの端を丸めます。



グラフ内のパーセンテージは10分の1に丸められ、100分の1になりましたが、フォントは非常に小さくなり、フォントはグラフのサイズに直接依存します。



グラフの色を属性に追加せず、スタイルでそれらを記述することにしました。



 /*    */ .dial { &.error { color: #d46d71; p { color: #d46d71; } } &.success { color: #689F38; border-color: rgba(#d46d71, 0.4); p{ color: #689F38; } } &.blue { color: #1390d4; } }
      
      





-私の意見ではより便利ですが、style =“ border-color:***;で色を指定する機会は常にあります。 色:*** "



デモ



ご清聴ありがとうございました。



All Articles