2014-09-24 19 views
1

我成功地建立了我海軍報圖,基於this previous post海軍報charts-觸發了一系列的開/關

我希望實現對查看器顯示/隱藏與點擊系列。 我發現了一堆解決方案,官方和其他人,但沒有一個爲我工作。 我會解釋:

  1. Official turning series on/off:這個作品,但看起來非常雜亂的傳說最終重複兩次(來自官方的傳說,一旦系列關閉消失)。
  2. Hiddengraphs.js:這是一個插件,可以在插件庫中找到,但它不能正常工作,並且與Chrome交互良好(嘗試使用多臺機器,但它不起作用)。
  3. This solution其實真的很不錯(我不介意沒有複選框來檢查),但是當我將它集成到我的代碼中時,我所得到的只是「跳躍」到頁面的頂部,並沒有任何反應。
  4. Lastly, I found this solution,它也適用,儘管使用另一個js庫,稱爲flot.togglelegend.js。 在這個實現中,我發現與flot.cust.js有一些重大沖突,無法讓他們一起工作。

這是我目前的JS(寫成的CoffeeScript)

colorArray = [] 
    colorArray.push "rgba(180, 0, 75, 0.6)" 
    colorArray.push "rgba(0, 150, 100, 0.6)" 
    colorArray.push "rgba(0, 0, 255,  0.6)" 
    colorArray.push "rgba(140, 0, 255, 0.6)" 
    colorArray.push "rgba(90, 180, 20, 0.6)" 
    colorArray.push "rgba(255, 236, 0, 0.6)" 
    colorArray.push "rgba(234, 170, 21, 0.6)" 
    colorArray.push "rgba(95, 180, 190, 0.6)" 
    colorArray.push "rgba(214, 92, 63, 0.6)" 
    colorArray.push "rgba(218, 106, 234, 0.6)" 
    colorArray.push "rgba(213, 128, 155, 0.6)" 

    # chart colors default 
    $chrt_border_color = "#efefef" 
    $chrt_grid_color = "#DDD" 
    $chrt_main = "#E24913" 

    # red  
    $chrt_second = "#6595b4" 
    # blue  
    $chrt_third = "#FF9F01" 
    # orange  
    $chrt_fourth = "#7e9d3a" 
    # green  
    $chrt_fifth = "#BD362F" 
    # dark red 
    $chrt_mono = "#000" 

    Chart = 

    generateDataObjects: (all_series, all_series_data) -> 
     plotData = [] 

     for series, i in all_series 
      obj = 
       label: series.replace /__/g, "|" 
       data: all_series_data[i] 
       color: colorArray[i] 

      plotData.push obj 

     return plotData 

    togglePlot: (seriesIdx) -> 
     someData = plot.getData() 
     someData[seriesIdx].lines.show = not someData[seriesIdx].lines.show 
     plot.setData someData 
     plot.draw() 
     return 

    getTooltip: (label, xval, yval, flotItem) -> 
      return 'Build: <span>'+ flotItem.series.data[flotItem.dataIndex][6]+'</span>' +" |  Run ID: <strong> #{flotItem.series.data[flotItem.dataIndex][7].toString()}</strong>" + '<br> Result: <span>'+Chart.commify(yval)+'</span>' 

    commify: (x) -> 
     return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 

    generateChartOptions: (legend_container, ticks) -> 
     return (
      series: 
       lines: 
        show: true 

       points: 
        show: true 

      crosshair: 
       mode: "x" 

      legend: 
       container: $("##{legend_container}") 
       labelFormatter: (label, series) -> 
        "<a href=\"javascript:void(0);\" onClick=\"Chart.togglePlot(" + series.idx + "); return false;\">" + label + "</a>" 
       noColumns: 4 
       # hideable: true 

      grid: 
       hoverable: true 
       clickable: true 
       tickColor: $chrt_border_color 
       borderWidth: 0 
       borderColor: $chrt_border_color 

      tooltip: true 
      tooltipOpts: 
       content : Chart.getTooltip 
       #content : "Value <b>$x</b> Value <span>$y</span>", 
       defaultTheme: false 

      xaxis: 
       ticks: ticks 
       rotateTicks: 30 

      selection: 
       mode: "xy" 
      ) 



    jQuery -> 
     if $("#normalized_bw_chart").length   # render only if the chart-id is present 

      raw_data = $("#normalized_bw_chart").data('results') 
      ticks = $("#normalized_bw_chart").data('ticks') 
      all_series = $("#normalized_bw_chart").data('series') 

      plot = $.plot($("#normalized_bw_chart"), Chart.generateDataObjects(all_series, raw_data), Chart.generateChartOptions('normalized_bw_legend', ticks))  

     if $("#concurrent_flows_chart").length  # render only if the chart-id is present 

      raw_data = $("#concurrent_flows_chart").data('results') 
      ticks = $("#concurrent_flows_chart").data('ticks') 
      all_series = $("#concurrent_flows_chart").data('series') 

      plot = $.plot($("#concurrent_flows_chart"), Chart.generateDataObjects(all_series, raw_data), Chart.generateChartOptions('concurrent_flows_legend', ticks)) 

     if $("#bandwidth_chart").length   # render only if the chart-id is present 

      raw_data = $("#bandwidth_chart").data('results') 
      ticks = $("#bandwidth_chart").data('ticks') 
      all_series = $("#bandwidth_chart").data('series') 

      plot = $.plot($("#bandwidth_chart"), Chart.generateDataObjects(all_series, raw_data), Chart.generateChartOptions('bandwidth_legend', ticks))  

     $("[data-behavior~=chart-selection]").bind "plotselected", (event, ranges) -> 
       selected_chart = $(this).attr('id')[0...-6] # slicing the name of the selected item 
       console.log ("zooming in to " + selected_chart) 
       plot = $.plot($("##{selected_chart}_chart"), plot.getData(), $.extend(true, {}, Chart.generateChartOptions(selected_chart+'_legend', ticks), 
        xaxis: 
        min: ranges.xaxis.from 
        max: ranges.xaxis.to 

        yaxis: 
        min: ranges.yaxis.from 
        max: ranges.yaxis.to 
       )) 
      return 

     $("[data-behavior~=chart-selection]").bind "dblclick", (event, pos, item) -> 
       selected_chart = $(this).attr('id')[0...-6] # slicing the name of the selected item 
       console.log ("zooming out to " + selected_chart) 
       plot = $.plot($("##{selected_chart}_chart"), plot.getData(), $.extend(true, {}, Chart.generateChartOptions(selected_chart+'_legend', ticks), 
        xaxis: 
        min: null 
        max: null 
       yaxis: 
       min: null 
       max: null 
      )) 
     return 

這裏有一個小提琴:http://jsfiddle.net/danklein/0tn1uzs9/3/

非常感謝!

+1

解決方案3.應該是簡單的這聽起來像在'labelFormatter'的'onClick'部分是不正確可能。你給了一個小提琴或代碼片段,它顯示了你的這個實現? – Raidri 2014-09-24 11:23:57

+1

我同意@Raidri,解決方案3(最初來自這個問題:http://stackoverflow.com/questions/14201911/dynamic-flot-graph-show -hide-series-by-clicking-on-legend-text-or-box-on-graph/14227287#14227287)是我見過的最直接的方法,它不適合你只是聽起來像是代碼中的一個bug。另外,如果需要,也可以很容易地添加複選框。 – Mark 2014-09-24 12:50:02

+0

@Mark,Raidiri,我認爲這確實是問題,但我無法弄清楚爲什麼Chart.togglePlot沒有達到。 我更新了我的代碼,用我最新的嘗試...... 請注意,我已將'#'更改爲'javascript:void(0);'以便頁面不會「跳轉」到其開始並重新加載點擊系列鏈接的時間(正如我前面提到的) – cyber101 2014-09-24 13:46:16

回答

2

1)當Chart對象的範圍不是全局時,直接在HTML中的onClick是一個壞主意。我改成一個jquery事件處理程序:

$('body').on 'click', 'a.legendtoggle', (event) -> 
    Chart.togglePlot($(this).data('index')) 
    return false 

2)series對象在labelFormatter函數沒有idx屬性,所以就用Chart對象內的變量:

labelFormatter: (label, series) -> 
    "<a href=\"#\" class=\"legendtoggle\" data-index=\"" + Chart.legendindex++ + "\">" + label + "</a>" 

3)I也會將您的plot對象放在Chart之內,以便它可以在togglePlot函數內進行訪問。我改變了linespoints因爲您的數據只有每一個系列數據點:

togglePlot: (seriesIdx) -> 
    someData = this.plot.getData() 
    someData[seriesIdx].points.show = not someData[seriesIdx].points.show 
    this.plot.setData someData 
    this.plot.draw() 
    return 

這應該是所有我變了,但自己比較,如果我得到的一切。
這裏是工作提琴:http://jsfiddle.net/jhpgtxz1/2/

PS:不要再CoffeeScript的我:-(

+0

這似乎很棒!謝謝! 我得到了'Uncaught TypeError:無法讀取'undefined'的屬性'點' 我搜索了一下,發現數據索引計數從2開始而不是0. 因此,我嘗試將'[seriesIdx]'改爲'[seriesIdx-2]',它工作。 另外,請注意,小提琴是我的實際頁面,其中包含三個圖形的樣機。其他兩個圖沒有反應... 最後,我在我的實際圖表中有兩條線和點,是否有任何方法將它們切換到一起,或者我應該只運行兩行代碼,每個屬性一行(行,點) – cyber101 2014-09-24 16:36:06

+0

你的三個圖表是否使用相同的圖例?如果不是,則需要分離圖形的點擊事件(不同的類或圖形否作爲數據屬性,例如)。是的,你需要兩行代碼點和線。 – Raidri 2014-09-24 20:29:43

+0

每個圖表都有一個不同的圖例(同一系列,但每個圖例都放在不同的容器下面,應該分開處理。所有圖表中都會提取點擊事件,但它們全部都是單獨更改的頂部圖表。 – cyber101 2014-09-24 20:35:04