2012-02-14 9 views
5

मैंने jQuery फ़्लोट चार्ट के लिए एक प्लगइन लिखा है जो आपको चार्ट की रेखा पर क्लिक करके डेटा बिंदुओं को गतिशील रूप से जोड़ने की अनुमति देता है, सही क्लिक करके उन्हें हटा देता है और यह ड्रैगिंग की अनुमति देता है कैनवास के आसपास इन बिंदुओं में से।फ़्लोट चार्ट - लाइन होवर पर घटना को कैसे फायर करें

यह ठीक काम करता है और मेरे पास वाई वैल्यू प्रदर्शित करने वाला टूलटिप भी होता है जब आप एक बिंदु को घुमाते हैं या खींचते हैं।

मैं जो करना चाहता हूं वह एक दूसरा टूलटिप प्रदर्शित करता है जब कोई उपयोगकर्ता "डेटा पॉइंट जोड़ने के लिए बायाँ-क्लिक" संदेश दिखाते हुए एक पंक्ति पर हो जाता है।

मुझे लगता है कि लाइन में एक होवर ईवेंट जोड़ने का कोई तरीका नहीं दिख रहा है और ऐसा कोई मूल तरीका प्रतीत नहीं होता है।

क्या कोई जानता है कि मैं इसे प्राप्त करने के बारे में कैसे जा सकता हूं?

धन्यवाद।

संपादित करें:

jsFiddle

के रूप में आप एक टूलटिप देख सकते हैं renders जब आप एक वास्तविक डाटापॉइंट पर होवर करें, फिर भी मैं करना चाहते हैं: यहाँ एक jsFiddle कि कि मैं उपयोग कर रहा हूँ टूलटिप निर्माण कोड भी शामिल है आग लगाने का एक तरीका ढूंढें जब आप डेटापॉइंट्स के बीच की रेखा पर होवर करते हैं तो एक अलग टूलटिप प्रस्तुत किया जाता है। नोट: इस पहेली में डेटापॉइंट्स को गतिशील रूप से जोड़ने और खींचने के लिए मेरा कस्टम कोड शामिल नहीं है क्योंकि यह इस प्रश्न के प्रयोजनों के लिए बहुत अधिक कोड होगा।

+0

उपयोगकर्ता टूलटिप पर कैसे होवर करता है? जब आप नियंत्रण से बाहर निकलते हैं तो टूलटिप दूर नहीं जाएगा? यदि आप एक उदाहरण दिखाते हैं, तो मैं आपकी मदद कर सकता हूं –

+0

डेटा पॉइंट के लिए टूलटिप फ़्लोट के मूल "प्लोथोवर" ईवेंट का उपयोग करके प्रदान किया जाता है जो उपयोगकर्ता को डेटापॉइंट पर घुमाने पर आग लगती है। हालांकि लाइन के लिए ऐसा कोई घटना नहीं है। एक उदाहरण मुश्किल पोस्ट होगा क्योंकि यह उस ऐप में कड़ाई से एकीकृत है जिसे मैं विकसित कर रहा हूं। मैं देखूंगा कि मैं क्या कर सकता हूं। – gordyr

+0

यहां तक ​​कि एक jsfiddle भी करेगा, लेकिन मुझे लगता है कि शायद कठिन हो सकता है –

उत्तर

5

तो मूल रूप से हम कर्सर की स्थिति को चार्ट पर एक पंक्ति से अधिक होने की आवश्यकता को पूरा करते समय सशर्त रूप से टूलटिप प्रदर्शित करने की सोच रहे हैं। चूंकि रेखाएं एक इकाई नहीं हैं, हम आपके साथ काम कर सकते हैं, अपने कर्सर के दोनों तरफ के निकटतम दो बिंदुओं के बीच की रेखा की गणना करने की आवश्यकता है और फिर देखें कि आपकी वर्तमान स्थिति उस पर है या नहीं। दो अंक के बीच की दूरी की गणना करने के

फंक्शन:: मैं अपने उदाहरण थोड़ा सरलीकृत

function lineDistance(p1x, p1y,p2x, p2y) { 
    return Math.sqrt((p2x - p1x)*(p2x - p1x) + (p2y-p1y)*(p2y-p1y)); 
} 

मानते हुए अपने निकटतम दो अंक अपने कर्सर सेल्सियस के लिए ए और बी हैं कि तो दूरी ABAC + BC बराबर होना चाहिए।

तो यह निर्धारित करने के लिए कि यह लाइन पर है: Math.abs(AB-(AC+BC)) < SomeThreshold। थ्रेसहोल्ड का उपयोग अनिवार्य रूप से उस रेखा के चारों ओर एक बॉक्स खींचता है जिसमें कर्सर अंदर आ सकता है।

फिर plothover (jsFiddle)

$(placeholder).bind("plothover", function (event, pos, item) { 
    if (item) { 
     var tipText; 

     if (opts.xaxis.mode === "time" || opts.xaxes[0].mode === "time") { 
      tipText = stringFormat(to.content, item, timestampToDate); 
     } else { 
      tipText = stringFormat(to.content, item); 
     } 

     $tip.html(tipText).css({ 
      left: tipPosition.x + to.shifts.x, 
      top: tipPosition.y + to.shifts.y 
      }).show(); 
    } else { 
     // Extended for line hover 
     var series = plot.getData(); 
     var xBeforeIndex = 0; 
     var xAfterIndex = -1; 
     var Threshold = 0.0000025; 
     var i = 1; 
     while (i <= series[0].data.length && xAfterIndex==-1) { 
      if (xAfterIndex == -1 && pos.x > series[0].data[i][0]) { 
       xBeforeIndex = i; 
      } else if (xAfterIndex == -1) { 
       xAfterIndex = i; 
      } 
      i++; 
     } 

     var onTheLine = 
      lineDistance(
       series[0].data[xBeforeIndex][0]/10000,series[0].data[xBeforeIndex][1], 
       pos.x/10000, pos.y) 
      +lineDistance(pos.x/10000, pos.y, 
       series[0].data[xAfterIndex][0]/10000,series[0].data[xAfterIndex][1]) 
      -lineDistance(
       series[0].data[xBeforeIndex][0]/10000,series[0].data[xBeforeIndex][1], 
       series[0].data[xAfterIndex][0]/10000,series[0].data[xAfterIndex][1]); 

      if (Math.abs(onTheLine) < Threshold) { 
       tipText = "Found Line"; 
       $tip.html(tipText).css({ 
        left: tipPosition.x + to.shifts.x, 
        top: tipPosition.y + to.shifts.y 
        }).show(); 
      } else { 
       $tip.hide().html(''); 
      } 
     } 
    }); 

हालात में अपने कोड का विस्तार यहाँ नहीं किया:

  1. अधिक उचित रूप से अपने एज मामलों की जांच करें - ऊपर पहली और आखिरी अंक पर हैं मान लिया गया है ग्राफ के किनारों।
  2. अपने दूसरे ग्राफ में वापस जोड़ें
  3. इंडेक्स के पहले/बाद में खोजने के लिए बबलसॉर्ट जैसे दृष्टिकोण का उपयोग करके डेटा सेट खोज प्रदर्शन में सुधार करें।
  4. ध्यान दें कि मैं एक्स-अक्ष को 10000 तक स्केल कर रहा हूं। संख्याएं बहुत बड़ी थीं और पहले दो बिंदुओं के बीच बड़े अंतर में वाई-अक्ष अंतर भिन्न थे (परिणाम इन दो बिंदुओं के बीच हमेशा शून्य था)।

नोट, दूसरे ग्राफ को जोड़ने के लिए आपको दोनों ग्राफों के लिए निकटतम बिंदु ढूंढने और जांचने की आवश्यकता होगी कि यह किसी भी रेखा पर पड़ता है या नहीं। यदि आपकी रेखाएं नज़दीक हैं या छेड़छाड़ कर रही हैं तो आप केवल प्राथमिकता रेखा बना सकते हैं। यदि आप दूसरी पंक्ति को वापस जोड़ने में संघर्ष करते हैं तो मैं बाद में मदद कर सकता हूं।

+0

यह नहीं पता था कि यह सवाल कितना पुराना था। हालांकि हल करने के लिए एक मजेदार समस्या थी - उम्मीद है कि यह किसी के लिए अभी भी उपयोगी है। – Matthew

+0

धन्यवाद, वास्तव में मदद करता है! –