Flot Chart Crosshair Plugin具有多个图表和动态图例

时间:2014-05-22 19:12:06

标签: javascript jquery charts flot

我有两个flot图表和三个数据集,两个图表和动态图例上的十字准线同步,表示图表上每个点的值。第二个图表中的图例没有显示其他两个工作正常的值。如何让第三个或更多传说显示动态值。此外,是否可以对现有代码进行改进,可以显示任意数量的同步十字准线图表?谢谢,

这是小提琴:http://jsfiddle.net/mashinista/Q24qN/

这是代码

plot = null;
plot2 = null;

var data1 = [
        [gd(2012, 0, 1), 8],
        [gd(2012, 1, 1), 13],
        [gd(2012, 2, 1), 4],
        [gd(2012, 3, 4), 8],
        [gd(2012, 4, 1), 16],
        [gd(2012, 5, 1), 20],
        [gd(2012, 6, 1), 29],
        [gd(2012, 7, 1), 23],
        [gd(2012, 8, 1), 28],
        [gd(2012, 9, 1), 16],
        [gd(2012, 10, 1), 8],
        [gd(2012, 11, 2), 4]
];


var data2 = [
        [gd(2012, 0, 1), 16],
        [gd(2012, 1, 1), 14],
        [gd(2012, 2, 1), 22],
        [gd(2012, 3, 1), 30],
        [gd(2012, 4, 1), 28],
        [gd(2012, 5, 1), 39],
        [gd(2012, 6, 1), 38],
        [gd(2012, 7, 1), 28],
        [gd(2012, 8, 1), 31],
        [gd(2012, 9, 1), 28],
        [gd(2012, 10, 1), 22],
        [gd(2012, 11, 1), 16]
];

var data3 = [
        [gd(2012, 0, 1), 16],
        [gd(2012, 1, 1), 14],
        [gd(2012, 2, 1), 22],
        [gd(2012, 3, 1), 30],
        [gd(2012, 4, 1), 28],
        [gd(2012, 5, 1), 39],
        [gd(2012, 6, 1), 29],
        [gd(2012, 7, 1), 23],
        [gd(2012, 8, 1), 28],
        [gd(2012, 9, 1), 16],
        [gd(2012, 10, 1), 8],
        [gd(2012, 11, 2), 4]
];

function gd(year, month, day) {
        return new Date(year, month, day).getTime();
}

$(function () {
    var sin = [], cos = []; 
    for (var i = 0; i < 14; i += 0.1) {
        sin.push([i, Math.sin(i)]);
        cos.push([i, Math.cos(i)]);
    }

    plot = $.plot($("#placeholder"),
                      [ { data: data1, label: "Query1 = 0.00"}, {
                data: data2, label: "Query2 = 0.00"}],
                  {
                            series: {
                                lines: { show: true }
                            },
                            crosshair: { mode: "x" },
                            grid: { hoverable: true, autoHighlight: false},
                            yaxis: { min: 0, max: 40 },
                          xaxis: {mode: "time"}
                        });

    plot2 = $.plot($("#placeholder2"),
                      [ { data: data3, label: "Query3 = 0.00"} ], {
                            series: {
                                lines: { show: true },
                                color: "#2eef34"
                            },
                            crosshair: { mode: "x" },
                            grid: { hoverable: true, autoHighlight: false},
                            yaxis: { min: 0, max: 40 },
                          xaxis: {mode: "time"}
                        });
    var legends = $("#placeholder .legendLabel, #placeholder .legendLabel");
    var updateLegendTimeout = null;
        var latestPosition = null;

        function updateLegend() {
                updateLegendTimeout = null;

                var pos = latestPosition;

                var axes = plot.getAxes();
                if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max || pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) return;

                var i, j, dataset = plot.getData();
                for (i = 0; i < dataset.length; ++i) {
                        var series = dataset[i];

                        // find the nearest points, x-wise
                        for (j = 0; j < series.data.length; ++j)
                        if (series.data[j][0] > pos.x) break;

                        // now interpolate
                        var y, p1 = series.data[j - 1],
                                p2 = series.data[j];
                        if (p1 == null) y = p2[1];
                        else if (p2 == null) y = p1[1];
                        else y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);

                        legends.eq(i).text(series.label.replace(/=.*/, "= " + y.toFixed(2) + " "));
                }
        }

        $("#placeholder").bind("plothover", function (event, pos, item) {
            plot2.setCrosshair({x: pos.x}),
                latestPosition = pos;
                if (!updateLegendTimeout) updateLegendTimeout = setTimeout(updateLegend, 50);
        });

     $("#placeholder2").bind("plothover", function (event, pos, item) {
                plot.setCrosshair({x: pos.x}),
                latestPosition = pos;
                if (!updateLegendTimeout) updateLegendTimeout = setTimeout(updateLegend, 50);
        });  
    });

1 个答案:

答案 0 :(得分:3)

有两个错误需要修复:

1)你的传说数组只包含第一个图中的图例:

var legends = $("#placeholder .legendLabel, #placeholder .legendLabel");

需要

var legends = $("#placeholder .legendLabel, #placeholder2 .legendLabel");

2)在updateLegend方法中,您只使用第一个图中的数据:

var i, j, dataset = plot.getData();

我在两个图/数据集上添加了for循环:

for (var p = 0; p <= 1; p++) {
    var i, j, dataset;
    if (p == 0) dataset = plot.getData();
    else dataset = plot2.getData();

    ...

    legends.eq(i + p * 2).text(series.label.replace(/=.*/, "= " + y.toFixed(2) + " "));

有关正常工作的代码,请参阅此更新的fiddle

3)更多图表:

如果要添加更多图表,则需要更改与上面相同的代码行。对于dataset,您可以使用switch语句或构建flot个对象数组,然后使用类似

的内容
var dataset = plot[p].getData();

对于图例编号,您必须计算每个图表的图例/数据的数量:

legends.eq(i + countOfLegendsFromOtherCharts(p)).text( ... );

有这样的东西(但可能更好地将这些值存储在某处):

function countOfLegendsFromOtherCharts(p) {
    var count = 0;
    for (var i = 0; i < p; i++) {
        var dataset = plot[p].getData();
        count += dataset.length;
    }
    return count;
}