Giter Club home page Giter Club logo

react-svg-timeline's Introduction

react-svg-timeline GitHub license npm version

A React event timeline component based on SVG.

  • Event Points & Periods
  • Event Tooltips
  • Event Lanes
  • Semantic Zoom (10 Years, 1 Year, 1 Week, 1 Day, etc)
  • Custom "rubber band" Zoom
  • Panning

Demo

Out of the box – plain & simple:

Explore our interactive demo for more details on customizations. The demo code can be found in the react-svg-timeline-demo repository.

Alternatively, you are free to use just the zooming & panning interaction logic, e.g. as a layer of the awesome Nivo line chart:

Installation

yarn add react-svg-timeline

or

npm install react-svg-timeline

Note that react and react-dom (version >=16.3) must already be installed.

Usage

This is the simplest possible way to get started:

import * as React from 'react'
import { Timeline } from 'react-svg-timeline'

export const App = () => {
  const laneId = 'demo-lane'
  const lanes = [
    {
      laneId,
      label: 'Demo Lane',
    },
  ]
  const events = [
    {
      eventId: 'event-1',
      tooltip: 'Event 1',
      laneId,
      startTimeMillis: 1167606000000,
      endTimeMillis: 1230698892000,
    },
    {
      eventId: 'event-2',
      tooltip: 'Event 2',
      laneId: laneId,
      startTimeMillis: 1399845600000,
    },
  ]
  const dateFormat = (ms: number) => new Date(ms).toLocaleString()
  return <Timeline width={600} height={300} events={events} lanes={lanes} dateFormat={dateFormat} />
}

Please check the react-svg-timeline-demo repository for a full-fledged feature demonstration.

Theming

To override the default theme, you can use the theme property.

If your project is using Material UI, the deriveTimelineTheme convenience function makes it particularly easy to use the MUI theme as a basis:

import * as React from 'react'

// MUI v4
import { useTheme } from '@material-ui/core'

// MUI v5
import { useTheme } from '@mui/material'

import { Timeline } from 'react-svg-timeline'

const App = () => {
  const materialTheme = useTheme()

  // MUI v4
  const type = materialTheme.palette.type

  // MUI v5
  const type = materialTheme.palette.mode

  const theme = deriveTimelineTheme(materialTheme.palette.mode, materialTheme)
  return <Timeline theme={theme} /** all other props here **/ />
}

If you would just like to override certain aspects of the default timeline theme, use the createTimelineTheme helper function:

const theme = createTimelineTheme({ event: { markFillColor: 'pink' } })

Library Development

Local Development

To run the timeline locally with HMR, execute the following command:

yarn start

Storybook

To run the storybook locally, execute the following command:

yarn storybook

Testing

To run the tests, execute the following command:

yarn test

Building

To build the library, execute the following command:

yarn build

Testing a release candidate

While making changes to this library in the context of a consuming project, yalc can be very handy:

In react-svg-timeline:

yalc publish

In your project consuming the library:

yalc add react-svg-timeline

Note: If you previously had react-svg-timeline added via yalc, you need to remove it first:

yalc remove react-svg-timeline
yarn install
yalc add react-svg-timeline

Publishing a release

Before publishing a release, make sure to update the version number in package.json.

git tag vX.Y.Z
(yarn npm login)
yarn npm publish
git push --tags

After publishing and pushing the tag, you can add a release on GitHub with autogenerated release notes.

Acknowledgements

Thank you:

License

Licensed under MIT License.

© Rahel Lüthy & Jan Azzati 2022

react-svg-timeline's People

Contributors

dependabot[bot] avatar dschaller avatar itsravenous avatar kashifshamaz21 avatar netzwerg avatar protyze avatar smonero avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-svg-timeline's Issues

Investigate usage of React Pose

Current hand-crafted animations are very sub-optimal...

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
    in Timeline
    in div
    in Unknown

Fix jittery cursor

The <MouseCursor> component manages the browser cursor through CSS. Consequently, when the cursor leaves the <MouseCursor> component, e.g. during mouse panning, it becomes very jittery, blinking back and forth between pointer and default.

Cursor state should preferably be kept in the top level <Timeline> component to prevent flickering.

Theme fixes & improvements

  • Fix bug that providing a different theme (e.g. via MUI switch) will not re-render timeline (v0.21.0)
  • Make theme optional again (possibility to create a default theme without providing a MUI template)
  • More control over styling of individual elements, with good defaults
  • Document theming in README
  • Fix/Extend tests

Remove circular dependencies

Listed upon yarn start:

Circular dependency: src/Timeline.js -> src/hooks/index.js -> src/hooks/useZoom.js -> src/index.js -> src/Timeline.js
Circular dependency: src/hooks/index.js -> src/hooks/useZoom.js -> src/index.js -> src/layers/interaction/index.js -> src/layers/interaction/Interaction.js -> src/hooks/index.js

Most likely caused by pseudo-encapsulation via index files

Refactor interaction handling

Pull all interaction logic up to InteractiveSvg component, such that MouseCursor component will be the pure visualization of a cursor.

Allows for cleaner cursor handling (no cursor during animations, proper updating of cursor once animation is done).

Possible states:

  • ready for zoom-in
  • ready for zoom-out
  • panning
  • rubber-band
  • animation in progress

Nivo charting example

I'm interested in accomplishing a timeline that mixes spans and points (as this tool displays events in the quickstart) with line charts like in the screenshot-nivo-layer.png example. I'm a bit confused as to how to make this happen - does the screenshot suggest that nivo charts can be embedded in the react-svg-timeline? Or does it instead mean some logic from this tool can be embedded in a nivo chart?

If there is an example that demonstrates how these tools interact somewhere that could be linked in the README, that would be awesome (the example code the generated the screenshot-nivo-layer.png would be perfect)!

Add Storybook

  • Add storybook (incl. GitHub Pages deployment)
  • Port existing example
  • Add example with larger data set
  • Add nivo interaction layer example

Support for custom layers

In order to provide further flexibility on how the react-svg-timeline can be used, we should support nivo-like custom layers.

Why are some of the events more opaque?

I'm trying to figure it out from the code itself but I'm lost. In the example demo and in my own code some of the events are a more opaque color than some other ones? What does this mean and how do I change it?

Option to use customised tooltips when items are hovered

Screen Shot 2021-02-22 at 6 54 31 PM

Hi @netzwerg ,

I would like to integrate this timeline component in my app. I have setup the library locally, and while playing around with the example code, when I tried to increase the content inside the tooltip, it didn't scale well. The content was cut-off.
Looking at the code for EventTooltip in Marks.tsx , it looks like the height of the tooltip is set to 30 and width is also constant.

const EventTooltip = ({ type, y, parentWidth, text, triggerRef }: EventTooltipProps) => {
  const classes = useTooltipStyle()
  const width = type === 'period' ? 180 : 100
  const height = 30
  ...

In my case, I need to show custom content inside the tooltip, whenever my custom icon items are hovered. Is it possible to accomplish this currently using the library's configuration options?

Screen Shot 2021-02-22 at 7 00 30 PM

PS: My tooltip content would have content along those lines. As you can see, the content is quite a bit, and hence to be able to show that, we have to provide a custom tooltip to be used instead of current default.

Thanks for any pointers you can provide on this.

Improve documentation

I know I can just dig the example code and figure it out by myself ... but a little explicit doc about the supported props and format would not hurt. Thanks.

Abstract over TimelineEvent

Making it possible to e.g. access custom event types of any shape or form in a safe manner.

Generically addresses the need behind #66

Esc does not completely reset zoom range

Pressing esc doesn't completely zoom you out, instead the zoom range is set to ~99% of the interpolated value between currentDomain and maxDomain (almost as if the animation skips the very last frame). Currently, you can press esc repeatedly to converge to the default zoom level.
The same goes for click followed by alt+click.

Can be observed in the interactive demo by looking at the displayed 'Zoom Range' value.

Rendering glitch when zooming from year to month on timeline

There appears to be an issue with date markers not appearing immediately when zooming in from the year-level view on the timeline to the month-level view. However upon dragging the timeline after being zoomed in, the markers re-appear again.

This issue was first discovered on my organization's own implementation of the timeline in our own React-based web app, but we have been able to reproduce it on the react-svg-timeline demo page as well (see the attached GIF). Is there a potential workaround for this behaviour we can implement on our side in the meantime?

Peek 2022-11-09 14-32

Extract example to separate repo

The live build/refresh cycle based on the dist folder is very shaky. We should rather use a cleanly separated repo and publish/consume test candidates via yalc.

  • Create repository
  • Transfer example folder status quo
  • Update demo link in README
  • Delete example folder

X-axis year font-size changes during zoom animation

Other axis labels (months and 10-year periods) behave consistently, yet year labels change greatly in size during zooming and can be very large when using rubber zooming.

Can currently be seen in the interactive demo.

Tooltip CSS Issue

@kashifshamaz21 @netzwerg
image
The tooltip is getting clipped near SVG boundaries. I tried using overflow: visible on parent div but in that case bottom timestamp gets distorted. Is there a way to fix it? Using derivedTimelineTheme i can only use backgroundColor, fontSize, fontFamily properties.

Odd warning that does not seem to impact performance

When I run my program I get:
WARNING in ./node_modules/ts-deepmerge/dist/index.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/Users/xxx/node_modules/ts-deepmerge/src/index.ts' file: Error: ENOENT: no such file or directory, open '/Users/xxx/node_modules/ts-deepmerge/src/index.ts'
Where xxx is the path to my program.

I am on version 0.23.3
It doesn't seem to harm anything but I would like this warning to be suppressed, either by you or if you could give me some way to suppress it myself it would be greatly appreciated

Make Interaction Mode Configurable

Currently the interaction layer can only be enabled/disabled as a whole by changing which layers should be rendered. However, there is no fine-grained control over which interaction modes should be enabled or not.

This functionality should be added, so that interaction modes can be defined via the timeline props.

Allow usage of built-in Layers outside of Timeline

Currently there is a dependency with the timelines theme provider that causes built-in layers that depend on the theme (like Interaction) to break when they are used outside of the react-svg-timeline (e.g. in a nivo component).

See usage of "useCursorStyle()" or "useZoomRangeStyle()" in MouseCursor.tsx.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.