ReactJS - SVG - Interactive Timeline
I would like to create an interactive timeline in React, as illustrated below:
General Info: The Timeline is showing items from a specified start date (top), until the current date (bottom). The items have each a date when they have occurred, and should be placed correctly within the available time-slots.
For the sake of simplicity, I would just like to focus on the following:
1. Drawing
2. Calculate the position of items
Could you please let me know if I'm on the right track with my following assumptions, or if you would suggest a different path?
- To draw the line I would use SVG without any further npm modules. The line will look the same no matter what start date(e.g. no matter if timeline starts 1991 or 2018)
- I want to calculate the position of each item based on the following factors:
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line)
2.2 One timeslots space will be - 100% length of line / overall amount of days to show
2.3 Items position will be calculated based on days since timeline start, meaning an item happened on the 2/11 will be presented in the 2nd / 30 timeslot
Would you also recommend to look back into basic math formulas again? :-)
Apart from that, if you have done something similar like this before and you could let me know any possible banana skins you are aware of, that would be much appreciated! Happy about ANY tips on this.
Thanks in advance!
javascript reactjs svg timeline
add a comment |
I would like to create an interactive timeline in React, as illustrated below:
General Info: The Timeline is showing items from a specified start date (top), until the current date (bottom). The items have each a date when they have occurred, and should be placed correctly within the available time-slots.
For the sake of simplicity, I would just like to focus on the following:
1. Drawing
2. Calculate the position of items
Could you please let me know if I'm on the right track with my following assumptions, or if you would suggest a different path?
- To draw the line I would use SVG without any further npm modules. The line will look the same no matter what start date(e.g. no matter if timeline starts 1991 or 2018)
- I want to calculate the position of each item based on the following factors:
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line)
2.2 One timeslots space will be - 100% length of line / overall amount of days to show
2.3 Items position will be calculated based on days since timeline start, meaning an item happened on the 2/11 will be presented in the 2nd / 30 timeslot
Would you also recommend to look back into basic math formulas again? :-)
Apart from that, if you have done something similar like this before and you could let me know any possible banana skins you are aware of, that would be much appreciated! Happy about ANY tips on this.
Thanks in advance!
javascript reactjs svg timeline
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line) here i think 23 timeslots should be there, can you explain how you got 30?
– Akash Salunkhe
Nov 20 '18 at 11:10
1
Hey, thanks for your comment. To double check, I've just literally opened calendar and counted the weeks (1/11 - 7/11 = 7, 8/11 - 14/11 = 7, 15/11 - 21/11 = 7, 22/11 - 28/11 = 7, plus the 29/11 and the 30/11. How did you come to 23? Sorry for any confusion Did you count work days only? As a background, this timeline is for a social media app and it's actually showing memories the user had with certain events. So full weeks count :-)
– Dusty48
Nov 20 '18 at 12:02
add a comment |
I would like to create an interactive timeline in React, as illustrated below:
General Info: The Timeline is showing items from a specified start date (top), until the current date (bottom). The items have each a date when they have occurred, and should be placed correctly within the available time-slots.
For the sake of simplicity, I would just like to focus on the following:
1. Drawing
2. Calculate the position of items
Could you please let me know if I'm on the right track with my following assumptions, or if you would suggest a different path?
- To draw the line I would use SVG without any further npm modules. The line will look the same no matter what start date(e.g. no matter if timeline starts 1991 or 2018)
- I want to calculate the position of each item based on the following factors:
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line)
2.2 One timeslots space will be - 100% length of line / overall amount of days to show
2.3 Items position will be calculated based on days since timeline start, meaning an item happened on the 2/11 will be presented in the 2nd / 30 timeslot
Would you also recommend to look back into basic math formulas again? :-)
Apart from that, if you have done something similar like this before and you could let me know any possible banana skins you are aware of, that would be much appreciated! Happy about ANY tips on this.
Thanks in advance!
javascript reactjs svg timeline
I would like to create an interactive timeline in React, as illustrated below:
General Info: The Timeline is showing items from a specified start date (top), until the current date (bottom). The items have each a date when they have occurred, and should be placed correctly within the available time-slots.
For the sake of simplicity, I would just like to focus on the following:
1. Drawing
2. Calculate the position of items
Could you please let me know if I'm on the right track with my following assumptions, or if you would suggest a different path?
- To draw the line I would use SVG without any further npm modules. The line will look the same no matter what start date(e.g. no matter if timeline starts 1991 or 2018)
- I want to calculate the position of each item based on the following factors:
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line)
2.2 One timeslots space will be - 100% length of line / overall amount of days to show
2.3 Items position will be calculated based on days since timeline start, meaning an item happened on the 2/11 will be presented in the 2nd / 30 timeslot
Would you also recommend to look back into basic math formulas again? :-)
Apart from that, if you have done something similar like this before and you could let me know any possible banana skins you are aware of, that would be much appreciated! Happy about ANY tips on this.
Thanks in advance!
javascript reactjs svg timeline
javascript reactjs svg timeline
asked Nov 20 '18 at 10:36
Dusty48Dusty48
489
489
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line) here i think 23 timeslots should be there, can you explain how you got 30?
– Akash Salunkhe
Nov 20 '18 at 11:10
1
Hey, thanks for your comment. To double check, I've just literally opened calendar and counted the weeks (1/11 - 7/11 = 7, 8/11 - 14/11 = 7, 15/11 - 21/11 = 7, 22/11 - 28/11 = 7, plus the 29/11 and the 30/11. How did you come to 23? Sorry for any confusion Did you count work days only? As a background, this timeline is for a social media app and it's actually showing memories the user had with certain events. So full weeks count :-)
– Dusty48
Nov 20 '18 at 12:02
add a comment |
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line) here i think 23 timeslots should be there, can you explain how you got 30?
– Akash Salunkhe
Nov 20 '18 at 11:10
1
Hey, thanks for your comment. To double check, I've just literally opened calendar and counted the weeks (1/11 - 7/11 = 7, 8/11 - 14/11 = 7, 15/11 - 21/11 = 7, 22/11 - 28/11 = 7, plus the 29/11 and the 30/11. How did you come to 23? Sorry for any confusion Did you count work days only? As a background, this timeline is for a social media app and it's actually showing memories the user had with certain events. So full weeks count :-)
– Dusty48
Nov 20 '18 at 12:02
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line) here i think 23 timeslots should be there, can you explain how you got 30?
– Akash Salunkhe
Nov 20 '18 at 11:10
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line) here i think 23 timeslots should be there, can you explain how you got 30?
– Akash Salunkhe
Nov 20 '18 at 11:10
1
1
Hey, thanks for your comment. To double check, I've just literally opened calendar and counted the weeks (1/11 - 7/11 = 7, 8/11 - 14/11 = 7, 15/11 - 21/11 = 7, 22/11 - 28/11 = 7, plus the 29/11 and the 30/11. How did you come to 23? Sorry for any confusion Did you count work days only? As a background, this timeline is for a social media app and it's actually showing memories the user had with certain events. So full weeks count :-)
– Dusty48
Nov 20 '18 at 12:02
Hey, thanks for your comment. To double check, I've just literally opened calendar and counted the weeks (1/11 - 7/11 = 7, 8/11 - 14/11 = 7, 15/11 - 21/11 = 7, 22/11 - 28/11 = 7, plus the 29/11 and the 30/11. How did you come to 23? Sorry for any confusion Did you count work days only? As a background, this timeline is for a social media app and it's actually showing memories the user had with certain events. So full weeks count :-)
– Dusty48
Nov 20 '18 at 12:02
add a comment |
1 Answer
1
active
oldest
votes
I liked the look of this so I thought I'd throw together a quick demo for you using the SVGGeometryElement API to fetch the line length and points along it. It's a pretty handy little interface. Run the following snippet to see it in action:
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391113%2freactjs-svg-interactive-timeline%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I liked the look of this so I thought I'd throw together a quick demo for you using the SVGGeometryElement API to fetch the line length and points along it. It's a pretty handy little interface. Run the following snippet to see it in action:
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
add a comment |
I liked the look of this so I thought I'd throw together a quick demo for you using the SVGGeometryElement API to fetch the line length and points along it. It's a pretty handy little interface. Run the following snippet to see it in action:
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
add a comment |
I liked the look of this so I thought I'd throw together a quick demo for you using the SVGGeometryElement API to fetch the line length and points along it. It's a pretty handy little interface. Run the following snippet to see it in action:
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
I liked the look of this so I thought I'd throw together a quick demo for you using the SVGGeometryElement API to fetch the line length and points along it. It's a pretty handy little interface. Run the following snippet to see it in action:
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
class SVGThingy extends React.Component {
state = {
points: ,
};
componentDidMount(){
const lineLength = this.path.getTotalLength();
const spanLength = lineLength / 30;
const points = new Array(31).fill('')
.map((p,i) => this.path.getPointAtLength(i * spanLength));
this.setState({points})
}
render() {
return (
<svg viewBox="0 0 240 200" width="240px" height="200px" >
<path ref={p => this.path = p} fill="none" stroke="red" strokeWidth="1" d="M 5.3 34.7 C 5.3 34.7 238.6 -29.5 232.6 23 C 222.4 114.6 5.3 12.3 2.9 83.9 C 0.5 155.5 232.3 40 230.8 106.1 C 228.7 190.2 4.3 100 4.1 158.9 C 3.9 218.4 241.9 127.9 193 194.9"/>
{this.state.points.map((p,i)=> (
<circle cx={p.x} cy={p.y} r="3" stroke="black" strokeWidth="2" fill="white"/>
))}
</svg>
);
}
}
ReactDOM.render( <SVGThingy />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react"></div>
answered Nov 20 '18 at 18:16
TedTed
11.1k12045
11.1k12045
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
add a comment |
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
Hey, apologies for the late reply. I could get a start today, and it worked out quite well. I have very much appreciated your effort putting this together! Helped me a lot to get an easy start! Thanks again!
– Dusty48
Nov 26 '18 at 9:38
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391113%2freactjs-svg-interactive-timeline%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2.1 One timeslot equals 1 day (e.g if the timeline shows 1/11 - 1/12, there will be 30 timeslots available - for the whole SVG line) here i think 23 timeslots should be there, can you explain how you got 30?
– Akash Salunkhe
Nov 20 '18 at 11:10
1
Hey, thanks for your comment. To double check, I've just literally opened calendar and counted the weeks (1/11 - 7/11 = 7, 8/11 - 14/11 = 7, 15/11 - 21/11 = 7, 22/11 - 28/11 = 7, plus the 29/11 and the 30/11. How did you come to 23? Sorry for any confusion Did you count work days only? As a background, this timeline is for a social media app and it's actually showing memories the user had with certain events. So full weeks count :-)
– Dusty48
Nov 20 '18 at 12:02