绘制图表 - 生成具有独特x轴值的自定义趋势 [英] Flot charts- producing custom trend with unique x-axis values

查看:79
本文介绍了绘制图表 - 生成具有独特x轴值的自定义趋势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有DB关系,其中包含我希望显示的信息。
每条记录都有一个数值,一个'name'看起来像'20140325_064532'。

I have DB relation that holds information that I wish to display. each record holds a numerical value, and a 'name' that looks like '20140325_064532'.

创建记录的顺序无关紧要,所以我希望在y轴和x轴上显示数值:

The order of creating the records doesn't matter, and so I wish to present the numerical value on the y-axis and the x axis to have:


  1. 恒定保证金在刻度之间。

  2. 根据'name'顺序(词典)显示数据。

  3. x轴标签不应显示所有值,而应显示选定的,以便不显示重叠。

  4. 以防止两个点放在相同的x值中,即使它们持有相同的名称(内部顺序没有任何意义)。

  1. to have constant margin between ticks.
  2. to present the data based on 'name' order (lexicographic).
  3. the x-axis label shouldn't present all the values, but "selected ones", such that no overlapping should be displayed.
  4. to prevent two point to be placed in the same x-value, even if they hold the same 'name' (the inner order has no meaning).

我应该如何定义我的Flot图表所以这可以实现吗?

how should I define my Flot chart so this can be achieved?

编辑:到目前为止我的实施想法:

EDIT: My implementation thoughts so far:


  1. 我将从DB中获取(明显地)'name'字段以及row_number值(从fr开始) om 1)。

  2. 基于此我将创建一个Hash,使用名称作为行号的关键字。让我们说:name => row#

  3. 我将生成具有以下结构的系列: rawdata = [[row#1 ,numericValue1],[row#2,numericValue2],....];

注意,行#将是一个数值开始在1。

Note that row# will be a numerical value starting at 1.

我将定义代表实际名称的刻度。 (这是带点的线图,而不是条形图。)

I'll define the ticks to represent the actual names. (This will be a line graph with dots, and not a bar chart).

现在,所有这将是有效的(我认为),但看起来非常混乱。
而且,在ontop上,滴答声几乎肯定会重叠,而且对于它将被硬编码的事实,任何放大和缩小都不会使得滴答声重叠。

更新#2:

我使用两个数据属性将数据传递给js。
'results'有一个代表该系列的数组,并保存4个字段,这样
data-results =[[[0,371144,20140206_000030-std ,375],[1,373141, 20140328_230027,343],[2,374196, 20140401_230051,436],[3,374734, 20140401_230051_2,460],[4,374394, 20140401_230051_3,484 ],[5,376029,20140401_230051_4,508]],...,[another_series]]]

I passed the data to the js using two data attributes. the 'results' has an array that representing the series, and holds 4 fields, such that data-results="[[[0,371144,"20140206_000030-std",375],[1,373141,"20140328_230027",343],[2,374196,"20140401_230051",436],[3,374734,"20140401_230051_2",460],[4,374394,"20140401_230051_3",484],[5,376029,"20140401_230051_4",508]],... ,[another_series]]]

第3个字段是'name',最后一个是'id'

The 3rd field is 'name' and the last one is 'id'

'series'重新表示我对每个系列的名称(以及它在图例中的显示方式),以及看起来像:

the 'series' reresents the name I have for each series (and how it is displayed in the legend), and looks like:

data-series="["PLATFORM_A__CONFIG_B","PLATFORM_B__CONFIG_NONE"]"

我尝试编辑工具提示的内容,尝试整合上一部分的信息每个点,所以我会显示这样的东西:
运行:
ID:
值:$ y(第二个数组字段,代表y轴值)

I tried editing the content of the tooltip trying to integrate information from the last part of each point, so that I'll have something like this displayed: Run: ID: value: $y (the 2nd array field, representing the y-axis value)

我搜索过了网络,但找不到任何有效的工具提示(看起来更好处理)。提到的文档中的

I searched the web but couldn't find anything that works using tooltip (which looks nicer to handle). in the docs it is mentioned:


如果您需要更多地控制工具提示的生成方式,那么
可以传递一个必须
的回调函数(label,xval,yval,flotItem)返回一个描述格式的字符串。

If you require even more control over how the tooltip is generated you can pass a callback function(label, xval, yval, flotItem) that must return a string with the format described.

我尝试通过调用Chart.getTooltip来实现这一点,但我在控制台中得到的只是

I tried implementing this by calling Chart.getTooltip but all I get in the console is

Uncaught TypeError: undefined is not a function jquery.flot.tooltip.min.js?body=1:2h jquery.flot.tooltip.min.js?body=1:2(anonymous function) jquery.flot.tooltip.min.js?body=1:2jQuery.event.dispatch jquery.js?body=1:4642elemData.handle jquery.js?body=1:4310jQuery.event.trigger jquery.js?body=1:4551(anonymous function) jquery.js?body=1:5261jQuery.extend.each jquery.js?body=1:384jQuery.fn.jQuery.each jquery.js?body=1:137jQuery.fn.extend.trigger jquery.js?body=1:5260Y jquery.flot.cust.min.js?body=1:2V jquery.flot.cust.min.js?body=1:2jQuery.event.dispatch jquery.js?body=1:4642elemData.handle jquery.js?body=1:4310

更新#3
感谢@Ryley的精彩提示和指导,我能够使用传递给Flot的唯一值正确显示我的图表。
我已更新我的代码,以便为了避免在ticks值中重叠,我使用 flot-tickrotor js来旋转外观。
我遇到了一个问题,我的最低价格被截止了。
我也注意到这是一个报告的问题,但是我找不到任何解决方案或解决方法。
这个问题有什么解决方案吗?

Update #3 Thanks to @Ryley great tips and guidance, I was able to correctly display my chart using the unique values passed into Flot. I've updated my code so that in order to avoid overlapping in the ticks values, I used flot-tickrotor js to rotate the looks. I've came across with a problem, in which my bottom values gets cut-off. I've also noticed that this is a reported issue, but I couldn't find any solution or workaround for this. Is there any solution for this issue?

接下来,我想让观众通过点击显示/隐藏系列。
我找到了许多解决方案,包括官方和其他人,但这些解决方案都不适用于我。
我会解释:

Next, I want to enable to viewer to show/hide the series with a click. I found bunch of solutions, both official and others, but none of those worked for me. I'll explain:


  1. 官方转动系列开启/关闭:这有效,但看起来非常混乱,因为传说最终被重复两次(一旦系列关闭就从官方传说中消失) 。

  2. Hiddengraphs.js :这是一个插件可以在插件存储库中找到,但它不起作用并与Chrome很好地交互(尝试过多台机器,它只是不起作用)。

  3. 此解决方案实际上非常好(我不是请注意,没有要检查的复选框),但当我将其集成到我的代码中时,我得到的只是跳转到页面顶部,没有任何反应。

  4. 最后,我找到了这个解决方案,它也可以使用另一个js库,名为 flot.togglelegend.js
    在这个实现中,我发现了一些与 flot.cust.js 的主要冲突,并且无法让它们一起工作。

  1. Official turning series on/off: this works, but looks very messy as the legend is eventually duplicated twice (disappears from official legend once the series turned off).
  2. Hiddengraphs.js: this is a plugin which can be found at the plugin repository, but it doesn't work and interact well with Chrome (tried more than one machine, it just don't work).
  3. This solution is actually really nice (I don't mind that there are no checkboxes to check), but when I integrated it into my code, all I got was "jumping" to the top of the page, and nothing happens.
  4. Lastly, I found this solution, which also works, altough using another js library, called flot.togglelegend.js. In this implementation I found some major conflicts with flot.cust.js, and couldn't get them both to work together.

最后,我尝试使用 flot实现select-zoom和双击zoom-reset。 selection.js
我确实能够使功能正常工作,但重新渲染过程会在第二个和第三个图表中生成第一个数据。

Finally, I tried to implement the select-zooming and double-click zoom-reset, using flot.selection.js I was able indeed to get the functionality to work, but the re-rendering process generates into my second and third chart the data of the first one.

同样值得一提的是,我在这个页面中渲染了3个图表,所有图表都以相同的方式呈现。

It is also worth saying that I'm rendering 3 charts in this page, all rendered in the same way.

这是我的更新代码:

这是我当前的js(用coffeescript编写)

Here's my current js (written in 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

getTooltip: (label, xval, yval, flotItem) ->
    return 'Build: <span>'+ flotItem.series.data[flotItem.dataIndex][2]+'</span>' +" | Run ID: <strong> #{flotItem.series.data[flotItem.dataIndex][3].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=\"#\" onClick=\"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 render chart-id存在

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

非常感谢!

推荐答案

好吧,你大部分都在那里,我刚刚为你完成了......

Well, you got most of the way there, I just finished it off for you...

基本问题:


  • 数据格式为 [[x1,y1],[x2,y2],...

 data: [[all_series_data[i][0],all_series_data[i][1]]]


  • 正确指定刻度(这只是抓住每一个奇数)

  • Specify ticks correctly (this just grabs every odd one)

    tick_labels = []
    for series, i in all_series
        if i % 2
            tick_labels.push [i,series]
        else
            tick_labels.push [i,'']  
    


  • 然后在你的情节选项中:

    and then in your plot options:

           xaxis:
                ticks: tick_labels  
    




    • 包含工具提示库并以默认方式使用它。我使用了来自 CDN的副本

    • 修复了一个基本的coffeescript语法错误(可能只是在这里复制它)。在你的 GenerateChartOptions 中,你打开一个,最后不要关闭它。

      • include the tooltip library and use it in the default way. I used a copy from a CDN.
      • fix a basic coffeescript syntax error (probably just from copying it over here). In your GenerateChartOptions you open a ( and never close it at the end.
      • 这是一个有效的例子: http:// jsfiddle .net / ryleyb / 0tn1uzs9 / 2 /

        Here's a working example: http://jsfiddle.net/ryleyb/0tn1uzs9/2/

        根据评论,我将此添加到示例中:

        Based on comments I added this to the example:

            #in the flot options
                tooltipOpts:
                    content: Chart.getToolTip
        
        #to the Chart object
        getToolTip: (label, xval, yval, flotItem) ->
            return 'Run: '+raw_data[xval][3]+': value: '+Chart.commify(yval)
        commify: (x) ->
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        

        这篇关于绘制图表 - 生成具有独特x轴值的自定义趋势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆