15

私はSVG の経験がほとんどなく、初めてRaphaëlを使用しています。この 2 つに詳しい人が助けてくれる必要があります。

動的セクターを含む円グラフを作成しました。丸いボタンをドラッグすると、セクターのサイズを変更できます。このフィドルを参照してください。必要なブラウザーである Chrome と Safari でのみテストしました。

円グラフはまだ完成していません。セクターはオーバーラップできます。今は無視してください。

セクターの開始角度が終了角度よりも大きい場合、問題に直面しました。これは、終了角度が 0/360° マークを超える場合です。これを解決するために、path- rotation -parameter を使用しました。終了角度が 360 になるまで、角度を戻しながらセクターを前方に移動しました。これは、この関数のフィドルで確認できます。

function sector_update(cx, cy, r, startAngle, endAngle, sec) {
    var x1 = cx + r * Math.cos(-startAngle * rad),
        x2 = cx + r * Math.cos(-endAngle * rad),
        y1 = cy + r * Math.sin(-startAngle * rad),
        y2 = cy + r * Math.sin(-endAngle * rad);


    var rotation = 0;

    // This is the part that I have the feeling could be improved.
    // Remove the entire if-clause and let "rotation" equal 0 to see what happens
    if (startAngle > endAngle) {
        rotation = endAngle;
        startAngle = startAngle - endAngle;
        endAngle = 360;
    }

    sec.attr('path', ["M", cx, cy, "L", x1, y1, "A", r, r, rotation, 
    +(endAngle - startAngle > 180), 0, x2, y2, "z"]);
}

うまく機能しますが、私は少し懐疑的です。これはパスを回転させずに解決できますか? 助けや指針をいただければ幸いです。

4

1 に答える 1

2

Can this be solved without the rotation of the path?

回答:はい、できます。パスの回転を変更する必要はまったくありません。私が何かを見逃していない限り、次のコードはあなたがフィドルに持っているものと同じように機能するようです:

function sector_update(cx, cy, r, startAngle, endAngle, sec) {
    var x1 = cx + r * Math.cos(-startAngle * rad),
        x2 = cx + r * Math.cos(-endAngle * rad),
        y1 = cy + r * Math.sin(-startAngle * rad),
        y2 = cy + r * Math.sin(-endAngle * rad);

    //notice there is no "roation" variable
    if (startAngle > endAngle) {
        startAngle -= endAngle;
        endAngle = 360;
    }

    sec.attr('path', ["M", cx, cy, "L", x1, y1, "A", r, r, 0, 
    +(endAngle - startAngle > 180), 0, x2, y2, "z"]);
}

説明: 私の説明では、 W3仕様およびRaphaelリファレンスライブラリのSVG用語を使用します。つまり、、、およびを使用している間、これらはそれぞれcx、、およびを使用します。cyrotationrxryx-axis-rotation

つまり、がにrx等しいときはいつでもryx-axis-rotation意味がありません。

このSVGを見てください。ブラウザの開発ツールを使用するか、SVGをコンピュータに保存し、ファイルエディタを使用して編集します。具体的には、path4つの円弧がある最後の要素を見てください。x-axis-rotation各アークの値を変更してみてください。値を更新しても、最初のアーク(rxryは両方とも「25」)は変更されないことに気付くでしょう。x-axis-rotation

なんで? これは、円弧があるためです。円をいくら回転させても、同じ円になります。たとえば、目の前にあるグラスを持ち上げて、グラスが地面に対して水平になるようにし、グラスを真下に見下ろします。次に、手首でガラスを回転/ねじります。あなたが見ている円形がどのように同じ円形のままであるかわかりますか?次に、ガラスを通常どおりテーブルに置きます(垂直で、液体を保持できるようにします)。次に、グラスをひっくり返します。明らかな視点の変化を見ることができます。上向きでしたが、今は平らになっています。それが何をするかx-axis-rotationです。

おそらく、より良い例は、前述のSVGファイルをいじってみることです。最後の要素x-axis-rotationの弧で遊んでください。path円弧が回転しているのがわかります。それが何をするかx-axis-rotationです。

コードに戻る: 円形のオブジェクトのみを扱っているためx-axis-rotation、最終的な出力に違いはありません。円形のオブジェクトのみを扱っている限り、心配することなくその値をゼロにハードコーディングできます。本当に必要なのは、正しく行った角度を変更することだけです。

パフォーマンス: JavaScriptを使用して、変数sector_updateを変更する場合と変更しない場合の両方で関数の時間を計測してみました。x-axis-rotation結果?パフォーマンスに違いは見られませんでした。費やされる時間の大部分は、SVGの値を決定する数学ではなく、実際にSVGを描画することに費やされます。実際、JavaScriptで実際に行っているのは、path要素に値を設定するようにコードを更新することだけです。その時点で、ブラウザはレンダリングエンジンを引き継ぎ、実際にSVGオブジェクトを描画します。ブラウザごとにレンダリングパフォーマンスが異なるため、これはブラウザごとの問題だと思います。x-axis-rotationしかし、その値が効果があるかどうかについては、私の推測ではありません。ある場合パフォーマンスの低下(ブラウザが追加の浮動小数点演算を実行する必要がある場合があるため)、オブジェクトの値の計算ではなく、オブジェクトの描画に圧倒的な時間の大部分が費やされるため、非常に重要ではありません。だから心配しないでください。

それがお役に立てば幸いです。何かを見逃したり、説明が不十分だったりした場合はお知らせください。

于 2012-07-22T03:19:49.773 に答える