2013-05-07 97 views
0

上Highcharts渲染正確定位我有我想要自定義形狀添加到基於該條價值和位置的Highcharts條形圖。首先,我試圖使用highcharts.renderer.path,爲每個條添加一條線條,與條形一樣高,位於X軸上,基於硬編碼值。這裏是我的意思圖片:用條形圖

example bar chart

這應該是容易的,它是當chart.type =「列」。在高圖回調中,我將在每個欄上使用getBBox(),並使用translate()將x軸值轉換爲像素值。

然而,試圖用chart.type =「欄」要做到這一點,當我碰到的一些問題。首先,切換所有的x和y值(我假設作者是如何從柱狀圖創建條形圖的第一位)。對於圖表的所有屬性也是如此:plotLeft現在是頂部,plotTop現在是左側。

這應該工作:

function (chart) { 
    $.each(chart.series[0].data, function (pointIndex, point) { 
     var plotLine = {}, 
      elem = point.graphic.element.getBBox(), 
      yStart, 
      xStart, 
      newline; 

     yStart = chart.plotTop+elem.x; 
     xStart = chart.plotLeft+elem.height; 

     plotLine.path = ["M", xStart, yStart+1, "L", xStart, yStart+point.pointWidth];   
     plotLine.attr = { 
      'stroke-width': 1, 
      stroke: point.color, 
      zIndex: 5 
     }; 

     newline = chart.renderer.path(plotLine.path).attr(plotLine.attr).add(); 
    });   
}); 

完整的示例:http://jsfiddle.net/Bh3J4/9/

第二個問題可能是無法克服的錯誤。看起來,當有多個數據點時,所有x和y值都會在點之間混合起來。在小提琴中注意顏色與位置不匹配。我創建了一個issue on GitHub

當有隻差一分,這不是一個問題。當有兩點時,我可以輕鬆切換值以獲得正確的定位。但是,如果有3個或更多的點,我似乎無法弄清楚值如何混淆的邏輯。

第三個問題,就是翻譯的功能似乎並沒有在X軸工作了柱狀圖,即使它在y軸。

chart.yAxis[0].translate(4); // correct for bottom axis 
chart.xAxis[0].translate(1); // incorrect for side axis 

是否有另一種方法來實現我在找什麼?我在那小提琴中錯過了什麼,這實際上不是一個錯誤?

+0

@zacarybrown發現,至少getBBox()的x值是反轉的條形圖:https://twitter.com/zacarybrown/status/332121728916529153 – simpixelated 2013-05-08 15:53:30

回答

1

我能夠實現我想要的結果,但我不知道這是否是巧合還是確實是個bug解決方法。無論如何,似乎使用來自逆向排序數組的x值幫助我正確地排列了所有內容。下面是highcharts回調函數:

function (chart) { 
    var benchmarks = { A: 1.5, B: 3.6, C: 2 }, 
     reverseData = _.clone(chart.series[0].data).reverse(); 

    _.each(chart.series[0].data, function (point, pointIndex) { 
     var plotLine = {}, 
      elem = point.graphic.element.getBBox(), 
      reverseElem = reverseData[pointIndex].graphic.element.getBBox(), 
      benchmark = benchmarks[point.category], 
      yStart = chart.plotTop+reverseElem.x, 
      xStart = chart.plotLeft+chart.yAxis[0].translate(benchmark), 
      yEnd = yStart+point.pointWidth-1; 

     plotLine.path = ["M", xStart, yStart+1, "L", xStart, yEnd];   
     plotLine.attr = { 
      'stroke-width': 1, 
      stroke: "red", 
      zIndex: 5 
     };   
     chart.renderer.path(plotLine.path).attr(plotLine.attr).add(); 

     var margin = 5, 
      xPadding = 10, 
      yPadding = 5, 
      xSplit = xPadding/2, 
      ySplit = yPadding/2, 
      text, 
      box; 

     text = chart.renderer.text("Top Perf Avg " + benchmark, xStart, yEnd+margin+16).attr({ 
      color: "#646c79", 
      align: "center", 
      "font-family": "Arial, sans-serif", 
      "font-size": 9, 
      "font-weight": "bold", 
      style: "text-transform: uppercase", 
      zIndex: 7 
     }).add(); 
     box = text.getBBox(); 
     chart.renderer.path(["M", box.x-xSplit, box.y-ySplit, 
          "l", (box.width/2)+xSplit-margin, 0, 
          margin, -margin, 
          margin, margin, 
          (box.width/2)+xSplit-margin, 0, 
          0, box.height+yPadding, 
          -(box.width+xPadding), 0, 
          0, -(box.height+yPadding)]) 
          .attr({ 
           'stroke-width': 1, 
           stroke: "#cccccc", 
           fill: "#ffffff", 
           zIndex: 6 
     }).add(); 

    }); 

} 

在這裏看到完整的工作圖:http://jsfiddle.net/Bh3J4/18/

0

在事實上,Highcharts旋轉使用transform一切,所以使用相同的旋轉這些行,見例如:http://jsfiddle.net/Bh3J4/19/

function (chart) { 
var d = chart.series[0].data, 
    len = d.length; 
for(var i =0; i < len; i++){ 

    var point = d[i], 
     plotLine = {}, 
     elem = point.graphic.element.getBBox(), 
     yStart, 
     xStart, 
     newline; 
    console.log(point,point.color); 
    xStart = point.plotX - point.pointWidth/2; 
    yStart = point.plotY; 

    plotLine.path = ["M", xStart, yStart, "L", xStart+point.pointWidth, yStart];   
    plotLine.attr = { 
     transform: 'translate(491,518) rotate(90) scale(-1,1) scale(1 1)', 
     'stroke-width': 1, 
     stroke: point.color, 
     zIndex: 5 
    }; 

    newline = chart.renderer.path(plotLine.path).attr(plotLine.attr).add(); 
}; 
} 
+0

這絕對接近,但你認爲你可以編輯你的小提琴,以便顏色匹配的路徑正好與酒吧(和他們的最後)排隊? – simpixelated 2013-05-09 19:59:00

0

輕微的調整,似乎給出精確定位:

請注意:更改爲xStart/yStart的計算並更改爲轉換轉換參數。 我的方法是讓它適用於柱形圖,然後翻譯得更精確。 唯一不能令人滿意的部分是xStart需要:'列'模式下的xStart = elem.x+chart.plotLeft;''欄模式下的xStart = elem.x; ...

function (chart) { 
var d = chart.series[0].data, 
    len = d.length; 
for(var i =0; i < len; i++){ 

    var point = d[i], 
     plotLine = {}, 
     elem = point.graphic.element.getBBox(), 
     yStart, 
     xStart, 
     newline; 
    console.log(point,point.color); 
    xStart = elem.x; 
    yStart = chart.plotHeight - (elem.height/2) + chart.plotTop; 

    plotLine.path = ["M", xStart, yStart, "L", xStart+point.pointWidth, yStart];   
    plotLine.attr = { 
     transform: 'translate(542.5,518) rotate(90) scale(-1,1) scale(1 1)', 
     'stroke-width': 5, 
     stroke: 'blue', 
     zIndex: 5 
    }; 

    newline = chart.renderer.path(plotLine.path).attr(plotLine.attr).add(); 
}; 
}