2

flot ライブラリを使用して、PNG 画像がポイントとしてレンダリングされるプロットをレンダリングしています。動作していますが、各 PNG 画像は 3 回レンダリングされているようです。これは更新時に表示されます (オーバーラップは完全ではありません)。また、画像の onload 関数をログに記録すると、Firebug は、グラフィックごとに 3 回呼び出されていることを通知します。画像をレンダリングする関数は次のとおりです (counter はログ変数です)。

function generateImageFunction (image) {
    return function getImage(ctx, x, y, radius, shadow) {                   
        var img = new Image();
        img.onload = function() {
            console.log(counter++);
            ctx.drawImage(img, x, y, img.width, img.height);    
        }
        img.src = image;
    }
}

データには 13 個の系列があります。これらは例として最初の 2 個です。

var data = [
            { 
             data: [[1, 1]], 
             points: { symbol: generateImageFunction("face-angel.png") }
            }
            { 
             data: [[2, 2]], 
             points: { symbol: generateImageFunction("face-angry.png") }
            }
           ];

私のオプションは次のとおりです。

var options = {
               series: {
                   points: { show: true },
               },
               xaxis: { min: 0, max: 15},
               yaxis: { show: false, min: 0, max: 15 },
               selection: { mode: "x" }
};

そして、私はします$.plot($("#placeholder"), data, options);

13 個のデータ シリーズでは、最初にページをロードしたときにカウンター変数が 39 になります。データ ポイントが 1 つしかない領域を拡大すると、カウンターが 3 増加します。なぜこれが起こっているのか、またはさらに調査するにはどうすればよいでしょうか?

4

2 に答える 2

5

コードが行うことは、flot がポイントを使用するたびに画像を再ダウンロードすることです。確かに、flot はおそらく呼び出しごとに 3 回使用するべきではありませんが、それ$.plotについてできることはあまりありません! できることは、画像を一度だけロードすることです!

function generateImageFunction(image) {
    return function getImage(ctx, x, y, radius, shadow) {
        ctx.drawImage(image, x, y, image.width, image.height);
    }
}

//list out all used images here
var symbols = {
    'icon1': 'http://tinychat.com/public/images/star.png',
        'icon2': 'http://www.earthdetails.com/images/icons/X-16-01.gif'
};
var symbol2image = {};//used to reference the downloaded image
var loading = [];//just used in the $.load call

//start loading each image
for (var symbol in symbols) {
    var img = new Image();
    img.src = symbols[symbol];
    symbol2image[symbol] = img;
    loading.push(img);
}

//wait until they are all loaded, then call the plot function
$.apply($, loading).load(function () {

   //setup data/options here, key lines being how you call the new generateImageFunction
                 symbol: generateImageFunction(symbol2image['icon2'])

   //call plot
    $.plot($("#placeholder"), data, options);
});

ここに実際の例があります: http://jsfiddle.net/ryleyb/kEhsQ/2/

于 2013-07-10T21:07:01.817 に答える
4

グローバルまたはシリーズごとの shadowSize オプションをオーバーライドしない限り、Flot は各シリーズの下に影を描画します。影は、不透明度を上げて境界線を柔らかくする 2 つのステップ (plotPoints 関数のコードを検索して、これがどのように行われるかを確認してください) で描画されます。

したがって、関数を 1 回実行してアルファ 0.1 で影を描画し、もう一度アルファ 0.2 で描画し、次にもう一度実際のシリーズを描画します。

これを望まない場合は、shadowSize を 0 に設定してシャドウを完全に無効にすることができます。関数の 'shadow' パラメータの値を確認することで、ポイントのみの影の描画をスキップすることもできます。true の場合、影を描画するために使用される 2 つの呼び出しに関しては、すぐに戻ることができます。

後者を使用する場合、@Ryleyが実際に画像を複数回ロードすることを避けるために提案したように、私も間違いなくそうします。

于 2013-07-10T22:33:02.867 に答える