NUKnightLab / TimelineJS3

TimelineJS v3: A Storytelling Timeline built in JavaScript. http://timeline.knightlab.com
Mozilla Public License 2.0
2.96k stars 620 forks source link

How to use timeline in REACT? #633

Closed shmilyoo closed 4 years ago

shmilyoo commented 4 years ago

For example, I want to switch different React components when I change the timeline node

JoeGermuska commented 4 years ago

We have not done any work to integrate TimelineJS with React. By far, our development has been focused on making it work well as an iframe embed.

To begin, you probably couldn't use it as an iframe embed. Messaging between iframes and their hosts when the pages are served from different servers is complex and requires development we haven't done.

You could instantiate the timeline on a page yourself in JavaScript. This, in itself, doesn't relate to React. However, the timeline should be sending events as various interactions happen, which, in principle, React or other JavaScript could listen for. This, too, is not something we've focused on or tested heavily, so for now, it would require looking through the code and working out a lot of things for yourself.

Formally developing, testing, and documenting Timeline's event system for deeper integration is not currently on our roadmap.

scott2b commented 4 years ago

There is a very basic React example in the contrib folder here: https://github.com/NUKnightLab/TimelineJS3/blob/master/contrib/examples/react.html

It might be dated at this point, and we don't use React much in the lab, so no promises really, but the example should provide an idea of how to get started.

benfoley commented 4 years ago

Based on @Granado's comment on the NPM issue #573, here's another approach to use the timeline in a React.js component.

Download the compiled version of timeline.js. In the beginning of the timeline.js script, add code to define and export TL. Then, rather than fixing all the lint errors which at this point will make the build fail, preface the lines with an eslint config line to disable linting errors and warnings.

/* eslint-disable */
var TL = {};
module.exports.TL = TL;

Create the TL.js file as described by @Granado.

var TL = require("./timeline"); 
TL = TL.TL._originalL; 
export default TL;

Make a React component,

import React, { useRef } from "react"
import TL from "../TL"

const TimelineComponent = () => {
  const timelineEl = useRef(null);
  let events = [PUT-YOUR-DATA-HERE];
  const timeline = new TL.Timeline(timelineEl.current, { "events": events });
  return (
      <div ref={timelineEl} className="timeline"></div>
  )
}
export default TimelineComponent
benfoley commented 4 years ago

However, there's a problem with displaying media when using the timeline in a React component. Images load OK but videos fail. Seems to be a problem with adding DOM elements.

Zynton commented 3 years ago

I believe const timeline = new TL.Timeline(timelineEl.current, { "events": events }); should be wrapped in a useEffect like this:

React.useEffect(() => {
    if (timelineEl.current) {
        const timeline = new TL.Timeline(timelineEl.current, { events: [] });
    }
}, []);

Otherwise timelineEl.current is passed to TL.Timeline before it actually has a dom element to reference.

Zynton commented 3 years ago

Using @benfoley 's explanation I got it to work for my (React Typescript) project and I thought I'd save other people the trouble by packaging it on npm.

If you guys have any problem with me packaging your library like this, let me know, I just thought it would be handy to have it as a ready-to-use React component like <Timeline events={...}/>.

JoeGermuska commented 3 years ago

Since we don't do a lot of React development, I'm happy to have someone who does be responsible for maintaining a library which works.

Note that, based on discussion in #705, beginning with TimelineJS 3.8.18 it should be more straightforward to import the Timeline class into code based around an npm workflow. This shouldn't impact the library created by @Zinston but let us know if that's incorrect.

shreyaagrawal0809 commented 3 years ago

Hey @benfoley Getting following errors. Can you please help out? 3:5 warning 'TL' is already defined no-redeclare 8:49 warning Unexpected use of comma operator no-sequences 17:7 error Expected an assignment or function call and instead saw an expression no-unused-expressions 19:74 warning Unexpected use of comma operator no-sequences 50:28 warning Unexpected use of comma operator no-sequences 62:7 warning 'use strict' is unnecessary inside of modules strict 74:7 error Expected an assignment or function call and instead saw an expression no-unused-expressions 77:11 warning Unexpected use of comma operator no-sequences 136:13 error Expected an assignment or function call and instead saw an expression no-unused-expressions 158:55 warning Unexpected use of comma operator no-sequences 781:23 warning Unnecessary escape character: - no-useless-escape 782:23 warning Unnecessary escape character: - no-useless-escape 784:74 warning Unnecessary escape character: - no-useless-escape 787:15 warning Unexpected control character(s) in regular expression: \x00 no-control-regex 850:38 warning Unexpected use of comma operator no-sequences 876:22 warning 'Rt' was used before it was defined no-use-before-define 969:13 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1017:9 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1017:17 warning Unexpected use of comma operator no-sequences 1090:15 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1090:71 warning Unexpected use of comma operator no-sequences 1145:27 warning Unexpected use of comma operator no-sequences 1146:63 warning Unexpected use of comma operator no-sequences 1155:27 warning Unexpected use of comma operator no-sequences 1164:27 warning Unexpected use of comma operator no-sequences 1233:21 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1237:25 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1237:77 warning Unexpected use of comma operator no-sequences 1249:15 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1249:52 warning Unexpected use of comma operator no-sequences 1297:15 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1306:51 warning Unexpected use of comma operator no-sequences 1315:13 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1315:18 warning Unexpected use of comma operator no-sequences 1318:13 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1318:24 warning Unexpected use of comma operator no-sequences 1327:13 error Expected an assignment or function call and instead saw an expression no-unused-expressions 1414:15 warning Unexpected control character(s) in regular expression: \x00 no-control-regex

benfoley commented 3 years ago

hi, these all look like ESLint errors. Looks like you need to work through your code to clean it up according to the lint rules you are using.

shreyaagrawal0809 commented 3 years ago

Thankyou so much for quick reply, now the errors have gone. @benfoley Just have one more question In the following line can I use json file by any chance for data?

let events = [PUT-YOUR-DATA-HERE];
benfoley commented 3 years ago

Yes you should be able to import data from json file and use that data in events. Look here for an example.

shreyaagrawal0809 commented 3 years ago

Thanks @benfoley for assisting me through this, can you please share the example of data you used to run the timeline? No matter how I am giving the data getting this error TypeError: Cannot read property 'Timeline' of undefined

Which means that the Timeline is not getting data in a particular format My data looks like this: [ { "timeline": { "headline": "Sht People Say", "type": "default", "title": "hello", "text": "People say stuff", "startDate": "2012,1,26", "date": [ { "startDate": "2011,12,12", "endDate": "2012,1,27", "headline": "Vine", "text": "

Vine Test

", "asset": { "media": "https://vine.co/v/b55LOA1dgJU", "credit": "", "caption": "" } }, { "startDate": "2012,1,26", "endDate": "2012,1,27", "headline": "Sht Politicians Say", "text": "

In true political fashion, his character rattles off common jargon heard from people running for office.

", "asset": { "media": "http://youtu.be/u4XpeU9erbg", "credit": "", "caption": "" } }, { "startDate": "2012,1,10", "headline": "Sh*t Nobody Says", "text": "

Have you ever heard someone say “can I burn a copy of your Nickelback CD?” or “my Bazooka gum still has flavor!” Nobody says that.

", "asset": { "media": "http://youtu.be/f-x8t0JOnVw", "credit": "", "caption": "" } }, ] } }

benfoley commented 3 years ago

Hi,

The data you shared is not valid JSON, so it is probably causing the import to fail.

Try using an online JSON validator such https://jsonlint.com/ https://jsonlint.com/ as to check and correct your data format.

Also, note that you can’t include multi line text in JSON. See https://stackoverflow.com/a/2392888 https://stackoverflow.com/a/2392888 for more info. Rather than using \n as suggested at that link, we used
tags which Timeline.js parses as HTML line breaks. B

On 19 Aug 2021, at 4:41 pm, shreyaagrawal0809 @.***> wrote:

Thanks @benfoley https://github.com/benfoley for assisting me through this, can you please share the example of data you used to run the timeline? No matter how I am giving the data getting this error TypeError: Cannot read property 'Timeline' of undefined

Which means that the Timeline is not getting data in a particular format My data looks like this: [ { "timeline": { "headline": "Sht People Say", "type": "default", "title": "hello", "text": "People say stuff", "startDate": "2012,1,26", "date": [ { "startDate": "2011,12,12", "endDate": "2012,1,27", "headline": "Vine", "text": "

Vine Test

", "asset": { "media": "https://vine.co/v/b55LOA1dgJU", "credit": "", "caption": "" } }, { "startDate": "2012,1,26", "endDate": "2012,1,27", "headline": "Sht Politicians Say", "text": " In true political fashion, his character rattles off common jargon heard from people running for office.

", "asset": { "media": "http://youtu.be/u4XpeU9erbg", "credit": "", "caption": "" } }, { "startDate": "2012,1,10", "headline": "Sh*t Nobody Says", "text": " Have you ever heard someone say “can I burn a copy of your Nickelback CD?” or “my Bazooka gum still has flavor!” Nobody says that.

", "asset": { "media": "http://youtu.be/f-x8t0JOnVw", "credit": "", "caption": "" } }, ] } }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NUKnightLab/TimelineJS3/issues/633#issuecomment-901651528, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABLD5GFJIRDA2QBYMKT6DXTT5SRQBANCNFSM4L3IQF7Q.

benfoley commented 3 years ago

This is the format of our title JSON data:

{
    "text":
    {
        "headline": "Timeline Headline goes here",
        "text": "A description can go here"
    }
}

This is the format of the events JSON we use.

[
    {
        "media":
        {
            "url": "https://link.to.file"
        },
        "start_date":
        {
            "year": "2017",
            "month": "01",
            "day": "01"
        },
        "text":
        {
            "headline": "A headline",
            "text": "Some text here"
        }
    },
    {
        "media":
        {
            "url": "https://link.to.another.file"
        },
        "start_date":
        {
            "year": "2006",
            "month": "01",
            "day": "01"
        },
        "text":
        {
            "headline": "Another headline",
            "text": "Some more text here"
        }
    }
]