0

Flot 折れ線グラフと FullCalendar のインスタンスの両方を自分のサイトにうまく統合しました。それらは両方とも別々のページにあります (ただし、ページは AJAX を介して div に読み込まれます)。

Flot Resize プラグインを追加したところ、完全に機能し、折れ線グラフのサイズが期待どおりに変更されました。ただし、カレンダーのサイズ変更時にエラーが発生するようです。

最初にカレンダー ページを読み込んでも、ウィンドウのサイズを変更すると、コンソールに次のエラーが表示されます (また、カレンダーのサイズが正しく変更されません)。

TypeError: 'undefined' is not an object (evaluating 'r.w=o!==c?o:q.width()')

エラーの原因を突き止めるのに苦労していたので、Flot Resize JS へのリンクを削除して、もう一度試しました。もちろん、折れ線グラフのサイズは変更されませんが、カレンダーのサイズを変更すると、正しく機能します。

2 つの要素の div コンテナーは異なる名前を持ち、(必要に応じて) 折れ線グラフを描画するために関数内からサイズ変更関数が呼び出されます。

Flot Resize プラグインへのリンクを別の場所 (つまり、fullCalendar JS の上/下、グラフを保持するテンプレート) に移動しようとしましたが、すべて役に立ちませんでした。

競合がどこにあるのか、どうすれば解決できるのか、誰にもわかりませんか??

どうもありがとう!

編集:ウィンドウのサイズを変更しなくても、フルカレンダーページの後に折れ線グラフ(flot)ページをロードするときにもエラーが発生するようです....今、私は非常に混乱しています!

EDIT 2: 折れ線グラフを描画するコード。この関数はページロード時に呼び出され、サーバーからプルされた JSON からデータを受け取ります。グラフが読み込まれると、まだ shutdown() が未定義であるというエラーが表示されます。

function plotLineGraph(theData){
var myData = theData['data'];
var myEvents = theData['events'];
var myDates = theData['dates'];

var events = new Array();
for (var i=0; i<myEvents.length; i++) {
    events.push(
        {
            min: myEvents[i][0],
            max: myEvents[i][1],
            eventType: "Calendar Entry",
            title: myEvents[i][2],
            description:  myEvents[i][3]
        }

    );
}

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

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

    if ($("#enableTooltip:checked").length == 0) {
        if (item) {
            if (previousPoint != item.dataIndex) {
                previousPoint = item.dataIndex;

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

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

var d1 = [
          myData[0],  myData[1],  myData[2],  myData[3],  myData[4],
          myData[5],  myData[6],  myData[7],  myData[8],  myData[9],
          myData[10], myData[11], myData[12], myData[13], myData[14],
          myData[15], myData[16], myData[17], myData[18], myData[19],
          myData[20], myData[21], myData[22], myData[23], myData[24],
          myData[25], myData[26], myData[27], myData[28], myData[29]
          ];
var markings = [
    { color: '#FFBDC1', yaxis: { from: 0, to: 2 } },
    { color: '#F2E2C7', yaxis: { from: 2, to: 3.5 } },
    { color: '#B6F2B7', yaxis: { from: 3.5, to: 5 } }
];

$.plot($("#placeholder"), [
    {label: "Average Daily Rating", data: d1, color: "black"}
    ], {
        events: {
            data: events,
        },
        series: {
            lines: { show: true },
            points: { show: true }
        },
        legend: { show: true, container: '#legend-holder' },
        xaxis: {
            ticks:[
            myDates[0],  myDates[1],  myDates[2],  myDates[3],  myDates[4],
            myDates[5],  myDates[6],  myDates[7],  myDates[8],  myDates[9],
            myDates[10], myDates[11], myDates[12], myDates[13], myDates[14],
            myDates[15], myDates[16], myDates[17], myDates[18], myDates[19],
            myDates[20], myDates[21], myDates[22], myDates[23], myDates[24],
            myDates[25], myDates[26], myDates[27], myDates[28], myDates[29]
            ],
        },
        yaxis: {
            ticks: 5,
            min: 0,
            max: 5
        },
        grid: {
            backgroundColor: { colors: ["#fff", "#eee"] },
            hoverable: true,
            clickable: true,
            markings: markings
        },
        selection: {
            color: 'white',
            mode: 'x'
        },
});
$('#placeholder').resize();
$('#placeholder').shutdown();
}

編集3:

カレンダーは次のように呼び出されます。

 function showCalendar() {
  var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();

$('#fullcalendar').fullCalendar({
    header: {
        left: 'prev',
        center: 'title',
        right: 'next'
    },
    clickable: true,
    firstDay: 1,
    eventSources: [
        {
            url: '/populate-calendar/{{theProductUuid}}/',
            color: 'black',
            data: {
                text: 'text'
            }
        }
    ],
    eventClick: function(calEvent, jsEvent, view) {
        var startDate = $.fullCalendar.formatDate(calEvent.start, 'yyyy-MM-dd');
        var endDate = $.fullCalendar.formatDate(calEvent.end, 'yyyy-MM-dd');
        var eventId = calEvent.uuid;
        $('#modal-event-title').text(calEvent.title);
        $('#edit-event-name').val(calEvent.title);
        $('#edit-start-date').val(startDate);
        $('#edit-end-date').val(endDate);
        $('#edit-event-text').val(calEvent.text);
        $('#edit-event-btn').attr('data-uuid', eventId);
        $('#modal-edit-event').on('click', '#delete-btn', function(){
            deleteCalendarEvent(eventId);
        });
        $('#modal-edit-event').modal();
        },
});

}

フロート チャートを含むページを読み込むための AJAX:

function loadDetailedReports(uuid){
$('#product-content').fadeOut('slow', function(){
    $('#product-content').empty();
    $('#whole-product-sub-nav .active').removeClass('active');
    $('#detailed-reports-content').load('/detailed-reports/' + uuid + '/', function(){
        $('#detailed-reports-btn').addClass('active');
        $('#detailed-reports-content').fadeIn('slow', function(){
            if (authorized){
                setLocationHash('loadDetailedReports&' + uuid);
                getChartData(uuid);
            } else {
            setLocationHash('');
            }
        });
    });
});
}

そして、カレンダーを含むページをロードするための AJAX:

function loadCalendar(uuid){
$('#detailed-reports-content').empty().hide();
$('#product-content').fadeOut('slow', function(){
    $('#whole-product-sub-nav .active').removeClass('active');
    $('#product-content').load('/calendar/' + uuid + '/', function(){
        $('#calendar-btn').addClass('active');
        $('#product-content').fadeIn('slow', function(){
            if (authorized){
                setLocationHash('loadCalendar&' + uuid);
            } else {
                setLocationHash('');
            }
            showCalendar();
        });
    });
});
}

.resize と .shutdown の呼び出しが存在するのは、サイズ変更機能を実現するために必要であるという印象を受け、シャットダウンに関する以前のコメントに応えて......おそらく n00b エラーです... ……?!?!

4

1 に答える 1

0

これは、jquery-resize の 198 行目でトリガーされているようです。

data.w = w !== undefined ? w : elem.width();

これは、異なるコンテンツを同じ div にロードする方法に起因する競合状態のように聞こえます。Flot は resize イベントをチャート div にバインドし、プロットが完全に破棄された場合にのみバインドを解除します。

編集: あなたのコードを見て、私の最初の提案は、plotLineGraph の最後にあるサイズ変更とシャットダウンの呼び出しを取り除くことです。サイズ変更プラグインはセットアップを必要としません。Flot にフックして、新しいプロットに自動的にアタッチします。したがって、サイズ変更の呼び出しは、実際には jQuery のサイズ変更イベント トリガーに対するものであり、これがエラーの原因である可能性があります。

編集#2:構造についてはまだ明確ではありませんが、一般化するために:(親を空にするなどして) #placeholder を取り除く可能性のある場所では、最初にプロットオブジェクトでシャットダウンを呼び出す必要があります。それへの参照を保持していない場合は、次のようにすることができます:$("#placeholder").data("plot").shutdown();ただし、最初のプロットを作成する前に、未定義であるという事実を考慮する必要があります。

それでもうまくいかない場合は、実際の (簡略化された) 例を見て、さらに提案する必要があります。

于 2012-10-23T15:27:30.663 に答える