Creating a scaling timeline in tkinter without matplotlib












0















I'm trying to create a timeline in tkinter to plot datetime objects. The dates may be years apart, but there won't be a great deal of them (20 max). I'd like the line to scale, so the first date is at the start of the line and the last is at the end of the line with markers for the dates in between.



I don't need it to do anything fancy, but I do need to show the distance between gaps of time rather than just an ordered grid of labels.



Whilst matplotlib has a great solution for this, I can't use it as it explodes the file size (I'm packaging this up) and I have no other use for it in the project. I've also looked at the ttkwidgets timeline but that's geared towards times rather than dates and hasn't seemed to work with the times I've given it.



As such, I'm thinking that I'll need to use a Canvas widget, and draw a line which scales dynamically. I'd then need to plot markers which take into account that scaling Any hints would be useful.










share|improve this question

























  • Well I have not voted yet but my guess at a glance is likely due to not providing your code attempt. "No code attempt" is often a reason for down voting.

    – Mike - SMT
    Jan 4 at 15:00
















0















I'm trying to create a timeline in tkinter to plot datetime objects. The dates may be years apart, but there won't be a great deal of them (20 max). I'd like the line to scale, so the first date is at the start of the line and the last is at the end of the line with markers for the dates in between.



I don't need it to do anything fancy, but I do need to show the distance between gaps of time rather than just an ordered grid of labels.



Whilst matplotlib has a great solution for this, I can't use it as it explodes the file size (I'm packaging this up) and I have no other use for it in the project. I've also looked at the ttkwidgets timeline but that's geared towards times rather than dates and hasn't seemed to work with the times I've given it.



As such, I'm thinking that I'll need to use a Canvas widget, and draw a line which scales dynamically. I'd then need to plot markers which take into account that scaling Any hints would be useful.










share|improve this question

























  • Well I have not voted yet but my guess at a glance is likely due to not providing your code attempt. "No code attempt" is often a reason for down voting.

    – Mike - SMT
    Jan 4 at 15:00














0












0








0


1






I'm trying to create a timeline in tkinter to plot datetime objects. The dates may be years apart, but there won't be a great deal of them (20 max). I'd like the line to scale, so the first date is at the start of the line and the last is at the end of the line with markers for the dates in between.



I don't need it to do anything fancy, but I do need to show the distance between gaps of time rather than just an ordered grid of labels.



Whilst matplotlib has a great solution for this, I can't use it as it explodes the file size (I'm packaging this up) and I have no other use for it in the project. I've also looked at the ttkwidgets timeline but that's geared towards times rather than dates and hasn't seemed to work with the times I've given it.



As such, I'm thinking that I'll need to use a Canvas widget, and draw a line which scales dynamically. I'd then need to plot markers which take into account that scaling Any hints would be useful.










share|improve this question
















I'm trying to create a timeline in tkinter to plot datetime objects. The dates may be years apart, but there won't be a great deal of them (20 max). I'd like the line to scale, so the first date is at the start of the line and the last is at the end of the line with markers for the dates in between.



I don't need it to do anything fancy, but I do need to show the distance between gaps of time rather than just an ordered grid of labels.



Whilst matplotlib has a great solution for this, I can't use it as it explodes the file size (I'm packaging this up) and I have no other use for it in the project. I've also looked at the ttkwidgets timeline but that's geared towards times rather than dates and hasn't seemed to work with the times I've given it.



As such, I'm thinking that I'll need to use a Canvas widget, and draw a line which scales dynamically. I'd then need to plot markers which take into account that scaling Any hints would be useful.







python python-3.x tkinter






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 10:43







Retro

















asked Jan 1 at 22:28









RetroRetro

1159




1159













  • Well I have not voted yet but my guess at a glance is likely due to not providing your code attempt. "No code attempt" is often a reason for down voting.

    – Mike - SMT
    Jan 4 at 15:00



















  • Well I have not voted yet but my guess at a glance is likely due to not providing your code attempt. "No code attempt" is often a reason for down voting.

    – Mike - SMT
    Jan 4 at 15:00

















Well I have not voted yet but my guess at a glance is likely due to not providing your code attempt. "No code attempt" is often a reason for down voting.

– Mike - SMT
Jan 4 at 15:00





Well I have not voted yet but my guess at a glance is likely due to not providing your code attempt. "No code attempt" is often a reason for down voting.

– Mike - SMT
Jan 4 at 15:00












1 Answer
1






active

oldest

votes


















1





+50









Ok so here is what I got so far. Its not perfect but it should be able it illustrate how one could build a dynamic timeline based on submitted dates.



This example will create labels on a canvas spaced out based on how many days are between them.



You will be able to click on the labels to get the notes that were saved with the day you clicked on.



I have provided a scrollbar for when you have many dates and cannot see them all on the screen.



You will also notice that you cannot submit the same day twice. Though you may wish to add a function that allows you to update the notes for that date.



You will need to pip install tkcalendar for this unless you wish to build your own date selector. But that is a lot of work for no good reason.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')

def on_click(self, event, data="No data!"):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_list.sort()
right_side = 50
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])

for ndex, date_item in enumerate(list_of_dates):
lbl = tk.Label(self.timeline_canvas, text=date_item[0][0], background='gray')
self.timeline_canvas.create_window((right_side, 25), window=lbl)
if ndex < len(list_of_dates)-1:
right_side += (65 + list_of_dates[ndex+1][1])

lbl.bind("<Button-1>", lambda event, d=date_item[0][1].strip(): self.on_click(event, d))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


Results:



enter image description here



Let me know if you have any questions.
I will work on this some more later if I have time.



UPDATE:



I have modified the code to consist on a line that is 500 pixels long.
I have done a bit of testing to make sure everything sits properly on the line.



I may modify it later if I find issues with it but for now I think this should work for all your listed needs.



I did notice one possible issue. Of a set of dates are really close to each other they will overlap each other if there is a large gap between the 1st and last date. I will try to find a better solutions but this is as far as I got today.



Update:



I have also added a zoom options that works with the mouse wheel. Right now you will have to use the scrollbar to move around the canvas when you zoom in but it should work for dates that are close and overlapping visually.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.line_size = 500
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')
self.timeline_canvas.bind_all("<MouseWheel>", self.zoom_in_out)

def zoom_in_out(self, event):
if event.delta < 0:
self.line_size -= 100
else:
self.line_size += 100
self.append_canvas()

def on_click(self, event=None, date=None, data=None):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(date, data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
self.timeline_list.sort()
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])
self.timeline_canvas.create_line(50, 50, 550, 50, fill="red", dash=(4, 4))
for ndex, date_item in enumerate(list_of_dates):
if ndex == 0:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((50, 50), window=lbl)
elif ndex == len(list_of_dates) - 1:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((self.line_size + 50, 50), window=lbl)
else:
x = (list_of_dates[ndex][1] / list_of_dates[-1][1]) * self.line_size
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((x + 50, 50), window=lbl)
lbl.bind("<Button-1>", lambda event, d=date_item[0][0], t=date_item[0][1].strip(): self.on_click(event, d, t))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


New results:



enter image description here






share|improve this answer


























  • Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

    – Retro
    Jan 6 at 15:38






  • 1





    @Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

    – Mike - SMT
    Jan 6 at 15:40











  • Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

    – Retro
    Jan 9 at 18:32






  • 1





    @Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

    – Mike - SMT
    Jan 9 at 18:36













  • Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

    – Retro
    Jan 10 at 22:13











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
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999438%2fcreating-a-scaling-timeline-in-tkinter-without-matplotlib%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









1





+50









Ok so here is what I got so far. Its not perfect but it should be able it illustrate how one could build a dynamic timeline based on submitted dates.



This example will create labels on a canvas spaced out based on how many days are between them.



You will be able to click on the labels to get the notes that were saved with the day you clicked on.



I have provided a scrollbar for when you have many dates and cannot see them all on the screen.



You will also notice that you cannot submit the same day twice. Though you may wish to add a function that allows you to update the notes for that date.



You will need to pip install tkcalendar for this unless you wish to build your own date selector. But that is a lot of work for no good reason.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')

def on_click(self, event, data="No data!"):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_list.sort()
right_side = 50
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])

for ndex, date_item in enumerate(list_of_dates):
lbl = tk.Label(self.timeline_canvas, text=date_item[0][0], background='gray')
self.timeline_canvas.create_window((right_side, 25), window=lbl)
if ndex < len(list_of_dates)-1:
right_side += (65 + list_of_dates[ndex+1][1])

lbl.bind("<Button-1>", lambda event, d=date_item[0][1].strip(): self.on_click(event, d))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


Results:



enter image description here



Let me know if you have any questions.
I will work on this some more later if I have time.



UPDATE:



I have modified the code to consist on a line that is 500 pixels long.
I have done a bit of testing to make sure everything sits properly on the line.



I may modify it later if I find issues with it but for now I think this should work for all your listed needs.



I did notice one possible issue. Of a set of dates are really close to each other they will overlap each other if there is a large gap between the 1st and last date. I will try to find a better solutions but this is as far as I got today.



Update:



I have also added a zoom options that works with the mouse wheel. Right now you will have to use the scrollbar to move around the canvas when you zoom in but it should work for dates that are close and overlapping visually.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.line_size = 500
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')
self.timeline_canvas.bind_all("<MouseWheel>", self.zoom_in_out)

def zoom_in_out(self, event):
if event.delta < 0:
self.line_size -= 100
else:
self.line_size += 100
self.append_canvas()

def on_click(self, event=None, date=None, data=None):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(date, data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
self.timeline_list.sort()
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])
self.timeline_canvas.create_line(50, 50, 550, 50, fill="red", dash=(4, 4))
for ndex, date_item in enumerate(list_of_dates):
if ndex == 0:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((50, 50), window=lbl)
elif ndex == len(list_of_dates) - 1:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((self.line_size + 50, 50), window=lbl)
else:
x = (list_of_dates[ndex][1] / list_of_dates[-1][1]) * self.line_size
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((x + 50, 50), window=lbl)
lbl.bind("<Button-1>", lambda event, d=date_item[0][0], t=date_item[0][1].strip(): self.on_click(event, d, t))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


New results:



enter image description here






share|improve this answer


























  • Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

    – Retro
    Jan 6 at 15:38






  • 1





    @Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

    – Mike - SMT
    Jan 6 at 15:40











  • Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

    – Retro
    Jan 9 at 18:32






  • 1





    @Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

    – Mike - SMT
    Jan 9 at 18:36













  • Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

    – Retro
    Jan 10 at 22:13
















1





+50









Ok so here is what I got so far. Its not perfect but it should be able it illustrate how one could build a dynamic timeline based on submitted dates.



This example will create labels on a canvas spaced out based on how many days are between them.



You will be able to click on the labels to get the notes that were saved with the day you clicked on.



I have provided a scrollbar for when you have many dates and cannot see them all on the screen.



You will also notice that you cannot submit the same day twice. Though you may wish to add a function that allows you to update the notes for that date.



You will need to pip install tkcalendar for this unless you wish to build your own date selector. But that is a lot of work for no good reason.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')

def on_click(self, event, data="No data!"):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_list.sort()
right_side = 50
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])

for ndex, date_item in enumerate(list_of_dates):
lbl = tk.Label(self.timeline_canvas, text=date_item[0][0], background='gray')
self.timeline_canvas.create_window((right_side, 25), window=lbl)
if ndex < len(list_of_dates)-1:
right_side += (65 + list_of_dates[ndex+1][1])

lbl.bind("<Button-1>", lambda event, d=date_item[0][1].strip(): self.on_click(event, d))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


Results:



enter image description here



Let me know if you have any questions.
I will work on this some more later if I have time.



UPDATE:



I have modified the code to consist on a line that is 500 pixels long.
I have done a bit of testing to make sure everything sits properly on the line.



I may modify it later if I find issues with it but for now I think this should work for all your listed needs.



I did notice one possible issue. Of a set of dates are really close to each other they will overlap each other if there is a large gap between the 1st and last date. I will try to find a better solutions but this is as far as I got today.



Update:



I have also added a zoom options that works with the mouse wheel. Right now you will have to use the scrollbar to move around the canvas when you zoom in but it should work for dates that are close and overlapping visually.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.line_size = 500
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')
self.timeline_canvas.bind_all("<MouseWheel>", self.zoom_in_out)

def zoom_in_out(self, event):
if event.delta < 0:
self.line_size -= 100
else:
self.line_size += 100
self.append_canvas()

def on_click(self, event=None, date=None, data=None):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(date, data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
self.timeline_list.sort()
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])
self.timeline_canvas.create_line(50, 50, 550, 50, fill="red", dash=(4, 4))
for ndex, date_item in enumerate(list_of_dates):
if ndex == 0:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((50, 50), window=lbl)
elif ndex == len(list_of_dates) - 1:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((self.line_size + 50, 50), window=lbl)
else:
x = (list_of_dates[ndex][1] / list_of_dates[-1][1]) * self.line_size
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((x + 50, 50), window=lbl)
lbl.bind("<Button-1>", lambda event, d=date_item[0][0], t=date_item[0][1].strip(): self.on_click(event, d, t))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


New results:



enter image description here






share|improve this answer


























  • Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

    – Retro
    Jan 6 at 15:38






  • 1





    @Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

    – Mike - SMT
    Jan 6 at 15:40











  • Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

    – Retro
    Jan 9 at 18:32






  • 1





    @Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

    – Mike - SMT
    Jan 9 at 18:36













  • Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

    – Retro
    Jan 10 at 22:13














1





+50







1





+50



1




+50





Ok so here is what I got so far. Its not perfect but it should be able it illustrate how one could build a dynamic timeline based on submitted dates.



This example will create labels on a canvas spaced out based on how many days are between them.



You will be able to click on the labels to get the notes that were saved with the day you clicked on.



I have provided a scrollbar for when you have many dates and cannot see them all on the screen.



You will also notice that you cannot submit the same day twice. Though you may wish to add a function that allows you to update the notes for that date.



You will need to pip install tkcalendar for this unless you wish to build your own date selector. But that is a lot of work for no good reason.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')

def on_click(self, event, data="No data!"):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_list.sort()
right_side = 50
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])

for ndex, date_item in enumerate(list_of_dates):
lbl = tk.Label(self.timeline_canvas, text=date_item[0][0], background='gray')
self.timeline_canvas.create_window((right_side, 25), window=lbl)
if ndex < len(list_of_dates)-1:
right_side += (65 + list_of_dates[ndex+1][1])

lbl.bind("<Button-1>", lambda event, d=date_item[0][1].strip(): self.on_click(event, d))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


Results:



enter image description here



Let me know if you have any questions.
I will work on this some more later if I have time.



UPDATE:



I have modified the code to consist on a line that is 500 pixels long.
I have done a bit of testing to make sure everything sits properly on the line.



I may modify it later if I find issues with it but for now I think this should work for all your listed needs.



I did notice one possible issue. Of a set of dates are really close to each other they will overlap each other if there is a large gap between the 1st and last date. I will try to find a better solutions but this is as far as I got today.



Update:



I have also added a zoom options that works with the mouse wheel. Right now you will have to use the scrollbar to move around the canvas when you zoom in but it should work for dates that are close and overlapping visually.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.line_size = 500
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')
self.timeline_canvas.bind_all("<MouseWheel>", self.zoom_in_out)

def zoom_in_out(self, event):
if event.delta < 0:
self.line_size -= 100
else:
self.line_size += 100
self.append_canvas()

def on_click(self, event=None, date=None, data=None):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(date, data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
self.timeline_list.sort()
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])
self.timeline_canvas.create_line(50, 50, 550, 50, fill="red", dash=(4, 4))
for ndex, date_item in enumerate(list_of_dates):
if ndex == 0:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((50, 50), window=lbl)
elif ndex == len(list_of_dates) - 1:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((self.line_size + 50, 50), window=lbl)
else:
x = (list_of_dates[ndex][1] / list_of_dates[-1][1]) * self.line_size
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((x + 50, 50), window=lbl)
lbl.bind("<Button-1>", lambda event, d=date_item[0][0], t=date_item[0][1].strip(): self.on_click(event, d, t))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


New results:



enter image description here






share|improve this answer















Ok so here is what I got so far. Its not perfect but it should be able it illustrate how one could build a dynamic timeline based on submitted dates.



This example will create labels on a canvas spaced out based on how many days are between them.



You will be able to click on the labels to get the notes that were saved with the day you clicked on.



I have provided a scrollbar for when you have many dates and cannot see them all on the screen.



You will also notice that you cannot submit the same day twice. Though you may wish to add a function that allows you to update the notes for that date.



You will need to pip install tkcalendar for this unless you wish to build your own date selector. But that is a lot of work for no good reason.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')

def on_click(self, event, data="No data!"):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_list.sort()
right_side = 50
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])

for ndex, date_item in enumerate(list_of_dates):
lbl = tk.Label(self.timeline_canvas, text=date_item[0][0], background='gray')
self.timeline_canvas.create_window((right_side, 25), window=lbl)
if ndex < len(list_of_dates)-1:
right_side += (65 + list_of_dates[ndex+1][1])

lbl.bind("<Button-1>", lambda event, d=date_item[0][1].strip(): self.on_click(event, d))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


Results:



enter image description here



Let me know if you have any questions.
I will work on this some more later if I have time.



UPDATE:



I have modified the code to consist on a line that is 500 pixels long.
I have done a bit of testing to make sure everything sits properly on the line.



I may modify it later if I find issues with it but for now I think this should work for all your listed needs.



I did notice one possible issue. Of a set of dates are really close to each other they will overlap each other if there is a large gap between the 1st and last date. I will try to find a better solutions but this is as far as I got today.



Update:



I have also added a zoom options that works with the mouse wheel. Right now you will have to use the scrollbar to move around the canvas when you zoom in but it should work for dates that are close and overlapping visually.



import tkinter as tk
from tkcalendar import Calendar


class Timeline(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(3, weight=1)
self.columnconfigure(0, weight=1)
self.timeline_list =
self.line_size = 500
self.timeline_canvas = tk.Canvas(self)
self.note_textbox = tk.Text(self, height=3)
self.text_label = tk.Label(self, text='Notes on date: ')
self.date_button = tk.Button(self, text='Submit new date', command=self.date_selector)
self.img = tk.PhotoImage(file='1x1.png')

self.date_button.grid(row=0, column=0)
self.text_label.grid(row=1, column=0)
self.note_textbox.grid(row=2, column=0, padx=5, pady=5, sticky="nsew")
self.timeline_canvas.grid(row=3, column=0, sticky='ew')

bar = tk.Scrollbar(self, orient='horizontal')
bar.config(command=self.timeline_canvas.xview)
bar.grid(row=4, column=0, sticky='ew')
self.timeline_canvas.bind_all("<MouseWheel>", self.zoom_in_out)

def zoom_in_out(self, event):
if event.delta < 0:
self.line_size -= 100
else:
self.line_size += 100
self.append_canvas()

def on_click(self, event=None, date=None, data=None):
"""You could build a popup menu here that
is activated on mouse-over or on-click
I just used print to test the field"""
print(date, data)

def append_canvas(self):
list_len = len(self.timeline_list)
if list_len > 1:
self.timeline_list.sort()
first_date = self.timeline_list[0][0]
last_date = self.timeline_list[-1][0]
line_length = last_date - first_date
self.timeline_canvas.delete('all')
list_of_dates =
for i in range(list_len):
if i == 0:
list_of_dates.append([self.timeline_list[i], 0])
elif i == list_len-1:
list_of_dates.append([self.timeline_list[i], line_length.days])
else:
list_of_dates.append(
[self.timeline_list[i], (self.timeline_list[i][0] - self.timeline_list[0][0]).days])
self.timeline_canvas.create_line(50, 50, 550, 50, fill="red", dash=(4, 4))
for ndex, date_item in enumerate(list_of_dates):
if ndex == 0:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((50, 50), window=lbl)
elif ndex == len(list_of_dates) - 1:
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((self.line_size + 50, 50), window=lbl)
else:
x = (list_of_dates[ndex][1] / list_of_dates[-1][1]) * self.line_size
lbl = tk.Label(self.timeline_canvas, text=ndex + 1, background='gray')
self.timeline_canvas.create_window((x + 50, 50), window=lbl)
lbl.bind("<Button-1>", lambda event, d=date_item[0][0], t=date_item[0][1].strip(): self.on_click(event, d, t))

def date_selector(self):
def work_selection():
selected_date = cal.selection_get()
selected_notes = self.note_textbox.get(1.0, 'end')
match_found = False
for each_list in self.timeline_list:
if selected_date == each_list[0]:
match_found = True
break
if match_found is False:
self.timeline_list.append([selected_date, selected_notes])
self.append_canvas()
top.destroy()
top = tk.Toplevel(self)
cal = Calendar(top, selectmode='day')
cal.pack(fill="both", expand=True)
tk.Button(top, text="ok", width=10, command=work_selection).pack()


if __name__ == "__main__":
Timeline().mainloop()


New results:



enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 8 at 18:09

























answered Jan 4 at 18:25









Mike - SMTMike - SMT

9,70121435




9,70121435













  • Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

    – Retro
    Jan 6 at 15:38






  • 1





    @Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

    – Mike - SMT
    Jan 6 at 15:40











  • Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

    – Retro
    Jan 9 at 18:32






  • 1





    @Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

    – Mike - SMT
    Jan 9 at 18:36













  • Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

    – Retro
    Jan 10 at 22:13



















  • Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

    – Retro
    Jan 6 at 15:38






  • 1





    @Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

    – Mike - SMT
    Jan 6 at 15:40











  • Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

    – Retro
    Jan 9 at 18:32






  • 1





    @Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

    – Mike - SMT
    Jan 9 at 18:36













  • Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

    – Retro
    Jan 10 at 22:13

















Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

– Retro
Jan 6 at 15:38





Hi Mike, thank you for your time, that's a fantastic start - just the sort of thing I was looking for. However, If you do happen to get any extra time I'd appreciate anything further you can do. The main issue is that with dates far apart (say 10 years) it causes a lot of scrolling - if you knew of a way to make the dates fit on a fixed sized canvas that would be great. No need for the dates (as they get a bit long) - representative numbers would work instead if that's easier and I can put a table to show which number refers to which date.

– Retro
Jan 6 at 15:38




1




1





@Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

– Mike - SMT
Jan 6 at 15:40





@Retro I think I could manage that. Instead of applying dates you can apply the index value of the list + 1. This would give you a number representation. Instead of spacing out each item basted on days apart you could do some math to limit the overall size to say 400 pixels wide so you can have a finite line that can scale with however many dates you need. I can probably work on this a little today. Let me see what I can do later when I get home.

– Mike - SMT
Jan 6 at 15:40













Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

– Retro
Jan 9 at 18:32





Hi Mike, did you get a chance to give it a look? no problem if you won't get chance.

– Retro
Jan 9 at 18:32




1




1





@Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

– Mike - SMT
Jan 9 at 18:36







@Retro I did update my post with my latest code. Check out the latest update at the bottom of my post and let me know if you have any questions. I believe it is much closer to what you were looking for.

– Mike - SMT
Jan 9 at 18:36















Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

– Retro
Jan 10 at 22:13





Absolutely fantastic - spot on and I've learnt a lot. Couldn't be happier!

– Retro
Jan 10 at 22:13




















draft saved

draft discarded




















































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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999438%2fcreating-a-scaling-timeline-in-tkinter-without-matplotlib%23new-answer', 'question_page');
}
);

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







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

Npm cannot find a required file even through it is in the searched directory

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith