график flot, используйте легенду, чтобы включить / выключить серию - PullRequest
6 голосов
/ 20 ноября 2010

Я хочу иметь возможность использовать легенду о графике с плавающей запятой, чтобы включить / выключить серию моего графика. Я нашел примеры на сайте flot и использовал серию Turning on / off и Labelformatter из API, чтобы построить то, что у меня есть сейчас. Я могу поставить флажки рядом с элементами легенды и добавить событие щелчка к ним и его событиям. Но это снова вызывает функцию plot и сбрасывает значения моего флажка. Я включил полную функцию jquery, извините, это немного долго.

<script id="source">
var jsonPath = "JsonPriceHistory/" + getParameterByName("CardId")



$(function () {
    $.getJSON(jsonPath, function (results) {

        results = [{ "label": "A", "data": [[1290115114240, 0.7000], [1289396258877, 0.7000], [1289394738247, 0.7000], [1288482602563, 0.7000], [1288479321830, 0.7000], [1288464257267, 0.7000], [1288463414413, 0.7000], [1268440264933, 1.0000], [1268434766653, 1.0000], [1268059707567, 1.0000], [1265934534340, 1.0000]] }, { "label": "B", "data": [[1290115102033, 6.0000], [1289395956947, 6.0000], [1289394743117, 6.0000], [1288482613967, 6.0000], [1288479332767, 6.0000], [1288464270420, 6.0000], [1288463427313, 6.0000], [1268440276413, 6.0000], [1268434778203, 6.0000], [1268059732683, 6.0000], [1265934545390, 6.0000]] }, { "label": "C", "data": [[1290115034640, 0.3000], [1289397347113, 0.3000], [1289396593083, 0.3000], [1289395047560, 0.3000], [1288484556080, 0.3000], [1288482794357, 0.3000], [1288465863503, 0.3000], [1288465248087, 0.3000], [1288464674300, 0.3000], [1268470601960, 0.6000], [1268469438957, 0.6000], [1268468281610, 0.6000], [1268440646800, 0.6000], [1265984810360, 0.8000], [1265955747730, 0.8000]] }, { "label": "C", "data": [[1290115031727, 0.1200], [1289397678960, 0.1200], [1289397337040, 0.1200], [1289396577510, 0.1200], [1289395024607, 0.1200], [1288484550417, 0.1200], [1288482780457, 0.1200], [1288465846327, 0.1200], [1288465231287, 0.1200], [1288464658213, 0.1200], [1268470586860, 0.2000], [1268469423697, 0.2000], [1268468266277, 0.2000], [1268440631390, 0.2000], [1265984774793, 0.2000], [1265955732580, 0.2000]] }, { "label": "D", "data": [[1290114958773, 0.0500], [1289397467207, 0.0500], [1289396747243, 0.0500], [1289395166640, 0.0500]] }, { "label": "E", "data": [[1290114933540, 0.6500], [1289397579447, 0.6500], [1289397242333, 0.6500], [1289396486657, 0.6500], [1289395003947, 0.6500], [1288484568590, 0.6500], [1288482784747, 0.6500], [1288465893750, 0.6500], [1288465278320, 0.6500], [1288464705170, 0.6500], [1268470629373, 0.6500], [1268469467810, 0.6500], [1268468309513, 0.6500], [1268440674610, 0.6500], [1265984889857, 0.6500], [1265955775453, 0.6500]] }, { "label": "F", "data": [[1290114885570, 0.1100], [1289396731507, 0.1100], [1289395170397, 0.1100]]}];

        var options = {
            legend: {
                show: true,
                container: $("#overviewLegend"),
                labelFormatter: function (label, series) {
                    var cb = '<input type="checkbox" name="' + label + '" checked="checked" id="id' + label + '"> ' + label;
                    return cb;
                }
            },
            series: {
                points: { show: true },
                lines: { show: true }
            },
            grid: { hoverable: true },
            xaxis: {
                mode: "time",
                minTickSize: [1, "day"],
                max: new Date().getTime()
            },
            yaxis: {
                mode: "money",
                min: 0,
                tickDecimals: 2,
                tickFormatter: function (v, axis) { return "$" + v.toFixed(axis.tickDecimals) }

            }
        };

        var i = 0;
        $.each(results, function (key, val) {
            val.color = i;
            ++i;
        });

        var choiceContainer = $("#overviewLegend");

        function plotAccordingToChoices() {
            var data = [];
            alert('hi');

            choiceContainer.find("input:checked").each(function () {
                var key = $(this).attr("name");
                if (key && results[key])
                    data.push(results[key]);
            });

            $.plot($("#placeholder"), results, options);
            choiceContainer.find("input").click(plotAccordingToChoices);
        }



        var previousPoint = null;
        $("#placeholder").bind("plothover", function (event, pos, item) {
            $("#x").text(pos.x.toFixed(2));
            $("#y").text(pos.y.toFixed(2));

            if (item) {
                if (previousPoint != item.datapoint) {
                    previousPoint = item.datapoint;

                    $("#tooltip").remove();
                    var x = item.datapoint[0].toFixed(2),
                y = item.datapoint[1].toFixed(2);

                    showTooltip(item.pageX, item.pageY, item.series.label + " $" + y);
                }
            }
            else {
                $("#tooltip").remove();
                previousPoint = null;
            }
        });

        function showTooltip(x, y, contents) {
            $('<div id="tooltip">' + contents + '</div>').css({
                position: 'absolute',
                display: 'none',
                top: y + 5,
                left: x + 15,
                border: '1px solid #fdd',
                padding: '2px',
                'background-color': '#fee',
                opacity: 0.80
            }).appendTo("body").fadeIn(200);
        }

        plotAccordingToChoices();
    })



});

1 Ответ

15 голосов
/ 20 ноября 2010

Есть пара проблем с вашим кодом:

Данные, которые вы используете, представлены в виде массива, в то время как данные, представленные в демоверсии, являются объектами. Различие здесь важно, потому что вы скопировали их код, но не изменили код, чтобы приспособиться к этому. Рассматриваемые строки:

if (key && results[key])
    data.push(results[key]);

внутри функции plotAccordingToChoices(). results[key] в вашем случае не будет работать, потому что key должно быть числовым значением, но key - это строка. Решение состоит в том, чтобы заменить это на цикл for, который ищет в массиве правильную метку:

for (var i = 0; i < results.length; i++) {
    if (results[i].label === key) {
        data.push(results[i]);
        return true;
    }
}

Далее, проблема заключается в том, что вы снова и снова выкладываете одни и те же данные, используя следующую строку:

$.plot($("#placeholder"), results, options);

results[] никогда не меняется - вместо этого следует использовать data[]:

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

Затем, в отличие от демо, вы решили установить флажки, используя функцию formatlabel в опции legend при построении графика. Проблема заключается в том, что при повторном построении графика с новыми данными, которые не содержат все результаты, флажки для непостроенных линий не будут отображаться, поскольку flot не будет отображать метки несуществующих линий.

Это означает, что вам нужно будет сделать то же, что и в демо-версии, - создать флажки отдельно. Мы делаем это, добавляя следующие строки в цикл $.each, который используется для исправления цветов, используемых каждой строкой:

l = val.label;
var li = $('<li />').appendTo(choiceContainer);

$('<input name="' + l + '" id="' + l + '" type="checkbox" checked="checked" />').appendTo(li);
$('<label>', {
    text: l,
    'for': l
}).appendTo(li);

Это создаст флажок - набор меток для каждого набора данных в массиве results. Наконец, мы перемещаем функцию для привязки plotAccordingToChoices к каждому флажку вне функции, чтобы привязка происходила только один раз, чтобы предотвратить множественные привязки и возникающий беспорядок:

choiceContainer.find("input").change(plotAccordingToChoices);

Мы также изменим его, чтобы использовать change событие вместо click, потому что change здесь более уместно.

И, наконец, в качестве бонуса мы перебираем таблицу легенды и вытягиваем оттуда цвета, чтобы добавить в список флажков:

$('.legendColorBox > div').each(function(i){
    $(this).clone().prependTo(choiceContainer.find("li").eq(i));
});

Нам также нужно немного CSS для этого:

#overviewLegend li > div {
    display: inline-block;
    margin-right: 4px;
}

Смотрите окончательный рабочий код здесь: http://jsfiddle.net/yijiang/6FLsM/2/

...