chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.69k stars 11.92k forks source link

Timeline Chart type #3574

Closed tuckwat closed 5 years ago

tuckwat commented 7 years ago

It would be great to have a Timeline Chart (like below) for plotting boolean values or states across a period of time. I may take a stab at a plug-in, has anyone attempted this or have any tips on where to start?

image

etimberg commented 7 years ago

I don't think i've seen this attempted before, but you might be able to reuse some of the horizontal bar stuff and you can definitely use the existing axes. I don't think there will be any major blocks

potatopeelings commented 7 years ago

@tuckwat - I think you should be able to achieve this with a stacked horizontal bar chart if you set those gaps to be datasets with backgroundColor transparent and with a scale callback - see http://jsfiddle.net/L56mxkuj/

You'll need to construct the data object though.

tuckwat commented 7 years ago

@potatopeelings - Great idea, thanks! It looks like it'll be a start but has some issues:

Do you think I should extend the horizontalBar or create a new chart type?

More advanced examples from Google Charts: https://developers.google.com/chart/interactive/docs/gallery/timeline

(sorry, didn't mean to close/re-open issue)

potatopeelings commented 7 years ago

Oh yeah. That was just something showing what it would look like and definitely had lots of issues. Here's a hopefully better one (https://jsfiddle.net/grugdbcf/) - still doesn't have proper tooltips and its mostly a hack.

fff8fe0e-270e-11e6-8675-f2dfb0594676

Do you think I should extend the horizontalBar or create a new chart type?

You could create a new chart type by extending horizontalBar - the methods you'd probably have to override is calculateBarBase and 'calculateBarX`.

tuckwat commented 7 years ago

@potatopeelings thanks for the help and examples. I started writing a new chart type rather than extending bar - I found that a dummy dataset works great for a single event per row but not so much for supporting multiple events.

I've got it working for linear series types but can't get it working with time scales. It looks like the time scale fails to use the time min/max values but I'm struggling to find a solution.

Here's an example working with linear scale: https://jsfiddle.net/tuckwat/zfdz89qs/

Modifed for time scale, getPixelForValue() returning NaN: https://jsfiddle.net/tuckwat/m61y05g9/1/

Thanks again for the help.

tuckwat commented 7 years ago

Well I think I figured it out. I was using a non-normal dataset structure for time series which was breaking the axis getPixelForValue. When you pass in an index and dataindex to the getPixelForValue function it tries to load it from a cache, which was built by looking at the labels. So the fix was to simply call getPixelForFunction(moment()) instead. 👍

lenyy commented 7 years ago

First let me thank you guys for this awesome library. Since in my company there was a need to create a TimeLine i decided to use your library to create a a new type of graph.

Here's the fiddle with the chart created https://jsfiddle.net/lenyy/2e0u7u3k/

So thanks to @tuckwat initiative and @potatopeelings hack i was able to create a new chart type, and so i have three questions:

  1. Would you like me to polish the timeLine graph so that you can distribute with charts, as you like it, being a sample or a new chart to add to the core.
  2. In the current design that i made for the chart i have to override a lot of functions from the rectangle because of the way i calculate the bar position and the tooltip itself, so the question really is if i should extend the rectangle element or leave it just like it is? If you have a better way to get the axes postions (x and y) and maintain the order of the rectangle element, then i ask for help :D .
  3. I've wondering around the base option for this kind of chart, i still can't imagine properly how to fit the base concept here, if you can help enlighten me in the subject would be awesome.

The future objective is to build this chart type with your plugin for pan and zoom built-in, because in my view this is used to represent dates, and i want to support more than one year in the data so a good way for the users to view the timeLine is to add support for pan and zoom plugin.

Any doubt about the code don't hesitate.

Thanks again and sorry if this wasn't the place to ask this, but i asked here because of the label assigned to this issue.

Cheers, Pedro

CJxD commented 7 years ago

I approve of this addition

larsnystrom commented 7 years ago

@lenyy's TimeLine chart looks really promising. Are there any plans to add it as a new chart type?

lenyy commented 7 years ago

Hi @larsnystrom i think you should first check the new improvements made by the charts team in https://github.com/chartjs/Chart.js/pull/3914 because they changed the way ticks are calculated so you should first check that. The work i did on the fiddler up there was changed to contain the new calculation of charts that the team is using now. To answer if it can be added as new chart type, i think you should ask the charts.js team about it, but i think they are open to PR on those matters(just a guess, not sure about it).

larsnystrom commented 7 years ago

I'm just not familiar enough with chart.js to be able to update the chart type to work with chart.js 2.6.

lenyy commented 7 years ago

@larsnystrom sorry but i can't post the code that i made because it was made for a company. Maybe when i have some spare time i can try and see if they still want a new chart type like a timeline or a gantt chart.

Cheers

MeTaNoV commented 7 years ago

Any update on the topic?

larsnystrom commented 7 years ago

You should probably open a new ticket, since this one has been closed for 10 months now. I think adding a timeline chart would be a nice addition to Chart.js, since it's not trivial to implement it (with tooltips and other common features of Chart.js) and it's a very useful type of chart.

MeTaNoV commented 7 years ago

@etimberg @larsnystrom why not re-open this issue instead of creating a new one?

larsnystrom commented 7 years ago

Because only the original author or a contributor can re-open issues, and the original author's problem is solved and I'm not a contributor. But if a contributor happens to see this, feel free to re-open this issue.

fanthos commented 7 years ago

It would be great if chartjs has timeline chart. Seems it can written as extension.

nenad-trenchevski commented 7 years ago

Can someone write an example with React maybe? ty

fanthos commented 6 years ago

I am trying to port timeline chart to current version, can I use your code at https://jsfiddle.net/lenyy/2e0u7u3k/ ? @lenyy

lenyy commented 6 years ago

Yes @fanthos you can you that version as base and try to change it your way

mlt commented 6 years ago

It would be nice to color and label (at least on mouse over) individual bars on a single line.

fanthos commented 6 years ago

I have a WIP plugin for timeline chart. https://github.com/fanthos/chartjs-chart-timeline

PaulWieland commented 6 years ago

@fanthos nice work. I found this because I want a chart to use with node-red to plot all of the events that occur in my house (lights on/off, motion on/off, doors open/close, etc).

Your JS Fiddle renders just fine, but for some reason the tool tip goes wonky when embedding your example in node-red. Any ideas?

In case you have node-red, here's a flow that embeds your example.

Screenshot of the problem

I hope this makes it into a future release!

fanthos commented 6 years ago

@fahrvergnuugen I have changed the data format. Following is the new data format:

"type": "timeline",
"data": {
    "labels": [
        "Cool Graph",
        "yeelight_UNKNOWN_34ce00bdf6b3",
        "heater1"
    ],
    "datasets": [
        {
            "data": [
                [
                    "2018-01-22T16:00:00.000Z",
                    "2018-01-23T05:40:44.626Z",
                    "Unknown"
                ]
            ]
        },
        {
            "data": [
                [
                    "2018-01-22T16:00:00.000Z",
                    "2018-01-23T05:40:44.626Z",
                    "On"
                ]
            ]
        },
        {
            "data": [
                [
                    "2018-01-22T16:00:00.000Z",
                    "2018-01-23T04:57:43.736Z",
                    "On"
                ],
                [
                    "2018-01-23T04:57:43.736Z",
                    "2018-01-23T04:57:55.437Z",
                    "Off"
                ],
                [
                    "2018-01-23T04:57:55.437Z",
                    "2018-01-23T05:40:44.626Z",
                    "On"
                ]
            ]
        }
    ]
},

Not sure I have all default values set up correctly.

Please refer to following links for details of the code: https://github.com/fanthos/home-assistant-polymer/blob/dev/src/components/entity/ha-chart-base.html https://github.com/fanthos/home-assistant-polymer/blob/dev/src/components/state-history-chart-timeline.html

PaulWieland commented 6 years ago

Since the data set is already an array of objects (each object containing a single "data" property) why not add the labels as a property too? Unless that breaks the chartjs pattern...

The reason I ask is because I'm encountering a situation where I have live streaming data coming into this chart that looks something like: {"topic":"Driveway Motion Sensor","value":true} and then a while later {"topic":"Driveway Motion Sensor","value":false}

Driveway Motion Sensor might not be part of the graph data yet, so I have to check and then add it to the labels array. If it does exist, I have to figure out which label index it has and then find the corresponding data set and append to it.

Granted, I can write helper functions for all of this, but I think if theres some flexibility with the way the dataset is structured, then it could be improved to make it easier.

FWIW my first attempt at building a dataset structure (before I found your chart plugin) looked like this:

{  
   "Garage":{  
      "label":"Garage",
      "row":0,
      "current":true,
      "timestamp":"2018-01-23T13:51:07.040Z",
      "history":[  
         {  
            "start":"2018-01-23T13:49:44.928Z",
            "stop":"2018-01-23T13:50:45.004Z"
         },
         {  
            "start":"2018-01-23T13:50:51.039Z",
            "stop":"2018-01-23T13:50:55.038Z"
         }
      ]
   },
   "Living":{  
      "label":"Living",
      "row":1,
      "current":true,
      "timestamp":"2018-01-23T13:51:03.038Z",
      "history":[  
         {  
            "start":"2018-01-23T13:50:30.988Z",
            "stop":"2018-01-23T13:51:01.038Z"
         }
      ]
   },
   "Kitchen":{  
      "label":"Kitchen",
      "row":2,
      "current":true,
      "timestamp":"2018-01-23T13:50:49.038Z",
      "history":[  

      ]
   },
   "Basement":{  
      "label":"Basement",
      "row":3,
      "current":false,
      "timestamp":"2018-01-23T13:50:06.953Z",
      "history":[  

      ]
   }
}
fanthos commented 6 years ago

I am using labels because I can do less modification for chartjs. Seems that chartjs needs labels property for Category axes.

PaulWieland commented 6 years ago

Still getting weird tooltip behavior: https://imgur.com/a/40hzI

fanthos commented 6 years ago

The tooltip works good on my side, so try to change the interaction mode to nearest. Maybe I forgot to setup the defaults for tooltip. http://www.chartjs.org/docs/latest/general/interactions/modes.html

PaulWieland commented 6 years ago

That was exactly it. Node-red (unbeknownst to me) had hard coded the tooltip behavior to a different type that was being inherited. It works well now!

mccrodp commented 6 years ago

Hey, what's the current status on adding a chart of type "Timeline"? We're currently using GoogleCharts, but it has many limitations at the moment, so would like to consider ChartsJS as we're also thinking about it's usage elsewhere. Lots of discussion here, but not sure where it's at other than nice looking JSFiddle hacks, rather than something in this codebase for Timeline? Cheers.

MBlistein commented 6 years ago

Hey @fanthos, I really like your solution, thanks for that! Unfortunately it won't let me change the font color on the rectangles; it sets it to white in most of my bright colors, e.g. rgba(0, 0, 255, 0.5) due to the luminosity check in the rectangle model, rendering the text unreadable. Also, with many bars, text only gets displayed sporadically on bars that are long enough. I would appreciate the possibility to turn off text on the bars. Could you provide some way of manipulating rectangle settings? It would be great if the rectangle element properties could be changed similar to the way to manipulate bar charts, e.g.:

options: {
    elements: {
        rectangle: {
        text: {
                display: false,
                textColor: 'rgba(0, 0, 0, 1),
            },
            borderWidth: 2,
        }
    }                 
}

Thanks!

corn98 commented 6 years ago

Hey @fanthos, I really like your plugin, well done!

Can you provide a JSFiddle example for this? And is possible use this with Chartjs v 2.7.x?

Thanks in advance!

Corn

abhsinh2 commented 6 years ago

https://jsfiddle.net/grugdbcf/ and https://jsfiddle.net/lenyy/2e0u7u3k/ dont work with Chartjs 2.7.2

fanthos commented 5 years ago

https://jsfiddle.net/fanthos/8vrme4bt/

marcus-at-localhost commented 5 years ago

Hey, with Charts.js 2.8 the dates are not working anymore.

https://jsfiddle.net/6fswnc9p/

There were two changes in 2.8 regarding time:

5960 Implement adapter to abstract date/time features

5982 Remove date auto type conversions

benmccann commented 5 years ago

@marcus-at-localhorst that was fixed in timeline 0.3.0: https://github.com/fanthos/chartjs-chart-timeline/releases/tag/v0.3.0

simonbrunel commented 5 years ago

Closing this issue since there is a plugin that implements the requested feature but also floating bars have been implemented in #6056 and will be released in v2.9.

benmccann commented 5 years ago

See https://github.com/chartjs/Chart.js/issues/6499 for additional details on usage