2012-07-02 95 views
4

在highcharts中,我試圖向點的數據標籤添加拖拽效果。我發現了一些針對特定標籤的方法。在這個小提琴中,你可以看到我的一些嘗試。 (我相結合,不同的嘗試在一個小提琴這裏炫耀什麼,我已經試過)製作dataLabel可拖拽

http://jsfiddle.net/EjwaX/3/

現在都使用chart.series [0]。數據[0] .dataLabel和使用點單擊事件使我可以更改dataLabel的屬性。不過,我無法將jquery ui .draggable()附加到標籤。是否有可能使圖表內的元素可拖動?

請讓我知道是否需要

+0

看到[更新的jsfiddle(http://jsfiddle.net/minagabriel/EjwaX/6/)我希望這是你想要什麼 –

+0

@Mina:所以爲什麼不把它作爲答案? –

+0

對不起,我只是發佈它 –

回答

1

任何詳細信息,實際上,你可以附上draggable小部件數據標籤就好了。但是,由於數據標籤爲SVG元素,因此它們完全忽略對其positionlefttop CSS屬性所做的更改。

取而代之的是包裝標籤露出transform屬性<g>元素:

<g zIndex="1" transform="translate(9, 152)"> 
    <!-- data label content --> 
</g> 

我們仍然可以使用draggable小部件(這是很方便,因爲它抽象的低級拖動事件)和更新transformdrag事件處理程序中的數據標籤包裝的屬性。由於拖動座標是相對的,因此我們必須解析原始的transform屬性並將結果座標用作原點。

現在,所有的標籤包裝都是由highcharts-data-labels類裝飾的團體的子女。這爲我們提供了一個很好的起點,所以我們可以寫類似:

$(".highcharts-data-labels").children().filter(function() { 
    var $this = $(this); 
    // Parse original translation. 
    var coords = $this.attr("transform") 
         .match(/translate\((-?\d+),\s*(-?\d+)\)/); 
    if (coords) { 
     // Associate origin with element. 
     return $this.data("origin", { 
      x: +coords[1], 
      y: +coords[2] 
     }); 
    } else { 
     // Parsing failed, reject element. 
     return false; 
    } 
}).draggable({ 
    drag: function(event, ui) { 
     var $this = $(this); 
     // Fetch back origin. 
     var origin = $this.data("origin"); 
     // Update current transform. 
     $this.attr("transform", "translate(" 
      + (origin.x + ui.position.left) + ", " 
      + (origin.y + ui.position.top) + ")"); 
    } 
}); 

你會發現一個更新的小提琴here

關於上面的代碼中的幾句話:

  • filter()是用來代替each(),因爲它使我們能夠過濾掉其transform屬性不能被解析(你永遠不知道)的元素,而不是徹底失敗,或餵養垃圾在drag處理程序中計算,

  • attr()代替prop()強調我們在SVG片段修改屬性的事實。 prop()可能會以完全相同的方式工作,所以這只是一個風格和個人偏好的問題。

最後一個警告:我只能測試這個在Firefox現在,但它似乎很難觸發一些標籤mousedown事件,特別是在曲線的部分「擁擠」的地方和數據提示競爭空間。調整數據標籤包裝的zIndex屬性並沒有取得多大成效。多次點擊有時會有所幫助。如果這在所有瀏覽器上都是一致的,則可能需要設計其他解決方案(可能是透明覆蓋,或者簡單地將mousedown事件從數據點本身傳遞到數據標籤)。

+0

這是輝煌的,正是我所期待的。然而,你是對的,當它變得擁擠時,它會變成一個問題,所以我會採取最後的建議,並從這些點本身傳達mousedowns。看起來像最好的解決方案,因爲用戶抓取比標籤要容易得多。感謝Frédéric的非常好的回答! – Sondre

0

working jsFiddle

$(document).ready(function() { 
    chart = new Highcharts.Chart({ 
     chart: { 
      renderTo: 'container', 
      type: 'line' 
     }, 
     title: { 
      text: 'Monthly Average Temperature' 
     }, 
     subtitle: { 
      text: 'Source: WorldClimate.com' 
     }, 
     xAxis: { 
      categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
       'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 
     }, 
     yAxis: { 
      title: { 
       text: 'Temperature' 
      }, 
      plotLines: [{ 
       value: 0, 
       width: 1, 
       color: '#808080' 
      }] 
     }, 
     plotOptions: { 
      series: { 
       dataLabels: { 
        enabled: true 
       }, 
       events: { 
        //Here I'm able to move the labels by using the click and shift-click. 
        //I wish to do this by dragging 
        click: function(event) { 
         var current_y = event.point.dataLabel.attr('y');       
         if(event.shiftKey) { 
          var new_y = current_y + 2; 
          event.point.dataLabel.attr({y: new_y}); 
         } else { 
          var new_y = current_y - 2; 
          event.point.dataLabel.attr({y: new_y});        
         } 
        } 
       }      
      } 
     }, 
     series: [{ 
      name: 'Tokyo', 
      data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] 
     }, { 
      name: 'New York', 
      data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5] 
     }, { 
      name: 'Berlin', 
      data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0] 
     }] 
    }); 

    //Second attempt to grab a point. Works for chaning attributes 
    var point = chart.series[0].data[0].dataLabel; 


} , function(chart){ 

}); 

$(function() { 
    console.log(chart) ; 
     $("#draggable").draggable() 
     .text(chart.series[0].data[0].y + 'drag and drop me  '); 
    });