3

まず第一に、私のhtml5とjavascriptのクエリで多くのことを助けてくれたウェブサイトとメンバーに感謝します。私の問題に取り掛かりましょう。私の縦棒グラフでは、canvasとjavascriptを使用して作成しました。ツールチップを含める必要があります。以下のコードと画像を提供するツールチップを開発しました。問題は、ツールチップが再描画されず、何度も描画されることです。

ここに画像の説明を入力してください

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
        window.onload=function() {
            var canvas=document.getElementById('mycanvas');
            var ctx=canvas.getContext('2d');
            var graphInfo=[{data:[120,130,140,160,180,100],color:'purple',label:["a","b","c","d","e","f"]},{data:[100,120,130,140,150,190],color:'green',label:["g","h","i","j","k","l"]}];
            var width=45;
             function renderGrid(gridPixelSize, color)
    {
        ctx.save();
        ctx.lineWidth = 0.5;
        ctx.strokeStyle = color;
        for(var i = 20; i <= canvas.height-20; i = i + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(20, i);
            ctx.lineTo(canvas.width-20, i);
            ctx.closePath();
            ctx.stroke();
        }
        for(var j = 20; j <= canvas.width-20; j = j + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(j, 20);
            ctx.lineTo(j, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
        }
        ctx.restore();
    }
   renderGrid(10, "grey");

            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.moveTo(20, canvas.height-20);
            ctx.lineTo(canvas.width-20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();

            ctx.beginPath();
    ctx.strokeStyle = 'black';
            ctx.moveTo(20, 20);
            ctx.lineTo(20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
            ctx.font = "bold 16px Arial";

    function getFunctionForTimeout(j){
                var i=0,currx=30,info=graphInfo[j],x5=j*5;
                var fTimeout=function(){
                    var h=Math.max(info.data[i]-x5,0);
                    var m=info.label[i];
                    ctx.fillStyle='black'
                    ctx.fillRect(currx+(10*x5)+2,canvas.height-h-20,width+2,h-1);
                    ctx.fillStyle=info.color;                   
                    ctx.fillRect(currx+(10*x5),canvas.height-h-21,width,h);                 
                    ctx.fillText(m, currx+(10*x5)+20, canvas.height-5);
                    currx+=120;  
                    i++;
                    if(i<info.data.length)setTimeout(fTimeout,0);
                     canvas.addEventListener('mousemove',function onMouseover(e) {
                        var mx = e.clientX - 8;
                        var my = e.clientY - 8;
                        ctx.save();
                        var str='X : ' + mx + ', ' + 'Y :' + my;
                        ctx.fillStyle = '#00ff00';
                        ctx.fillRect(mx + 10, my + 10, 70, 20);
                        ctx.fillStyle = '#000';
                        ctx.font = 'bold 20px verdana';
                        ctx.fillText(str, mx + 10, my + 25, 60);
                        ctx.restore();
                    }, 0);
                };
                return fTimeout;
    }

            for(var j=graphInfo.length-1;j>=0;j--) {
                setTimeout(getFunctionForTimeout(j),2000);
            }
        };
        </script>
    </head>
    <body>
        <canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
    </body>
</html>
4

3 に答える 3

1

HTML5 Canvas は SVG や HTML とは異なります。要素を追加および削除したり、属性を変更したりして、再描画されることを期待することはできません。キャンバスに何かを描くと、それは永続的です。何かを「移動」するには、キャンバス ( clearRect()) を消去し、ツールチップを使用して新しい場所にコンテンツを再度描画する必要があります。

または、ツールチップにキャンバスを使用しないことをお勧めします。なぜですか?代わりに、ツールチップを別の HTML (または SVG) 要素として作成し、移動してください。コンポジットの再描画はブラウザに任せてください。

于 2012-07-27T15:30:05.400 に答える
0

ヒント ボックスを描画した後、キャンバスが必要restoreですか? それはうまくいかないと思います。まず定義を見てみましょうsave/restore

環境 。save() 現在の状態をスタックにプッシュします。

環境 。restore() スタックの最上位の状態をポップし、コンテキストをその状態に復元します。

では、「現状」とは?

仕様から

描画状態は次のとおりです。

  • 現在の変換行列。
  • 現在のクリッピング領域。
  • 次の属性の現在の値:
    • ストロークスタイル、
    • フィルスタイル、
    • グローバルアルファ、
    • 線幅、
    • ラインキャップ、
    • ラインジョイン、
    • miterLimit、
    • lineDashOffset、
    • shadowOffsetX、
    • shadowOffsetY,
    • シャドウブラー、
    • シャドウカラー、
    • グローバルコンポジット操作、
    • フォント、
    • テキスト整列、
    • テキストベースライン、
    • imageSmoothingEnabled。
  • 現在のダッシュ リスト。

含まない:

現在のデフォルト パスと現在のビットマップは、描画状態の一部ではありません。現在のデフォルト パスは永続的であり、beginPath() メソッドを使用してのみリセットできます。現在のビットマップは、コンテキストではなくキャンバスのプロパティです。

のような操作が必要だと思いますundo。前者はBase64でエンコードされた画像を返し、その画像をキャンバスに描画するために使用toDataURLすることをお勧めします。または、あなたはそれをグーグルすることができますdrawImagedrawImage

于 2012-07-27T12:39:05.613 に答える
0

前回は getMousePos() メソッドを使用してマウスの x と y の位置を取得し、それをツールチップに配信したので、このコードを試してみてください..(今はアラートです) :)

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
        window.onload=function() {
            var canvas=document.getElementById('mycanvas');

            canvas.addEventListener('mousemove', function(evt) {
                  var mousePos = getMousePos(canvas, evt);
                  var message = "Mouse position: " + mousePos.x + "," + mousePos.y;
                  //alert(message);
                }, false);

            var ctx=canvas.getContext('2d');
            var graphInfo=[{data:[120,130,140,160,180,100],color:'purple',label:["a","b","c","d","e","f"]},{data:[100,120,130,140,150,190],color:'green',label:["g","h","i","j","k","l"]}];
            var width=45;
             function renderGrid(gridPixelSize, color)
    {
        ctx.save();
        ctx.lineWidth = 0.5;
        ctx.strokeStyle = color;
        for(var i = 20; i <= canvas.height-20; i = i + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(20, i);
            ctx.lineTo(canvas.width-20, i);
            ctx.closePath();
            ctx.stroke();
        }
        for(var j = 20; j <= canvas.width-20; j = j + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(j, 20);
            ctx.lineTo(j, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
        }
        ctx.restore();
    }
   renderGrid(10, "grey");

            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.moveTo(20, canvas.height-20);
            ctx.lineTo(canvas.width-20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();

            ctx.beginPath();
    ctx.strokeStyle = 'black';
            ctx.moveTo(20, 20);
            ctx.lineTo(20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
            ctx.font = "bold 16px Arial";

            function getMousePos(canvas, evt) {
                var rect = canvas.getBoundingClientRect(), root = document.documentElement;

                // return relative mouse position
                var mouseX = evt.clientX - rect.top - root.scrollTop;
                var mouseY = evt.clientY - rect.left - root.scrollLeft;
                return {
                  x: mouseX,
                  y: mouseY
                };
              }
    function getFunctionForTimeout(j){
                var i=0,currx=30,info=graphInfo[j],x5=j*5;
                var fTimeout=function(){
                    var h=Math.max(info.data[i]-x5,0);
                    var m=info.label[i];
                    ctx.fillStyle='black'
                    ctx.fillRect(currx+(10*x5)+2,canvas.height-h-20,width+2,h-1);
                    ctx.fillStyle=info.color;                   
                    ctx.fillRect(currx+(10*x5),canvas.height-h-21,width,h);                 
                    ctx.fillText(m, currx+(10*x5)+20, canvas.height-5);
                    currx+=120;  
                    i++;
                    if(i<info.data.length)setTimeout(fTimeout,0);
                     canvas.addEventListener('mousemove',function onMouseover(e) {
                        var mx = e.clientX - 8;
                        var my = e.clientY - 8;
                        ctx.save();
                        var str='X : ' + mx + ', ' + 'Y :' + my;
                        ctx.fillStyle = '#00ff00';
                        ctx.fillRect(mx + 10, my + 10, 70, 20);
                        ctx.fillStyle = '#000';
                        ctx.font = 'bold 20px verdana';
                        ctx.fillText(str, mx + 10, my + 25, 60);
                        ctx.restore();
                    }, 0);
                };
                return fTimeout;
    }

            for(var j=graphInfo.length-1;j>=0;j--) {
                setTimeout(getFunctionForTimeout(j),2000);
            }
        };
        </script>
    </head>
    <body>
        <canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
    </body>
</html>
于 2012-07-27T12:45:38.027 に答える