2

I am using the flot library to render a plot where PNG images are rendered as points. It's working, but each PNG image seems to be rendered three times. This is visible on a refresh (the overlap isn't perfect), and I also logged the image's onload function and Firebug tells me that it is being called three times for each graphic. Here is the function that renders the images (counter is the logging variable):

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;
    }
}

data has 13 series, these are just the first two as an example:

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

My options are these:

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

And then I do $.plot($("#placeholder"), data, options);

With the 13 data series, the counter variable goes to 39 when I first load the page. If I zoom in on a region with only one data point, the counter is increased by 3. Can anyone tell me why this is happening, or what can I do investigate further?

4

2 回答 2

5

What your code does is re-download the image every time the point is used by flot. Admittedly, flot probably should not be using it 3 times per $.plot call, but there's not much you can do about that! What you can do is load the image only once!

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);
});

There is a working example here: http://jsfiddle.net/ryleyb/kEhsQ/2/

于 2013-07-10T21:07:01.817 回答
4

除非您覆盖全局或每个系列的 shadowSize 选项,否则 Flot 将在每个系列下方绘制阴影。阴影是分两步绘制的(搜索 plotPoints 函数的代码以了解这是如何完成的)增加不透明度,以软化其边界。

因此,您的函数运行一次以在 alpha 0.1 处绘制阴影,再次在 alpha 0.2 处绘制阴影,然后再次绘制实际系列。

如果您不希望这样,您可以通过将 shadowSize 设置为零来完全禁用阴影。您也可以通过检查函数的“shadow”参数的值来跳过仅为点绘制阴影;如果是真的,至于用于绘制阴影的两个调用,那么您可以立即返回。

如果您选择后者,那么我肯定也会按照@Ryley 的建议来避免实际多次加载图像。

于 2013-07-10T22:33:02.867 回答