Made analytics more powerfull

This commit is contained in:
Jeison Yehuda Amihud (Blender Dumbass) 2023-01-04 18:05:16 +00:00
parent 8d12e15f07
commit beb6d23f85
4 changed files with 273 additions and 59 deletions

View file

@ -388,6 +388,23 @@ def draw(outlayer, win, path, back="story_editor"):
"settings/themes/"+win.settings["Theme"]+"/icons/checklist.png",
5, 5, 40, 40)
# If not in the analytics window. I want to have a button to go to analyitcs.
if win.url != "analytics":
reducing = 60
def do():
win.cur = "/set"
win.url = "analytics"
UI_elements.roundrect(layer, win,
width - 55,
5,
40,
40,
10,
do,
offset=[x,y],
icon="analytics")
else:
reducing = 0
# Fraction
fraction = win.checklists[path]["fraction"]
@ -396,7 +413,7 @@ def draw(outlayer, win, path, back="story_editor"):
UI_elements.roundrect(layer, win,
50,
17,
width - 60,
width - 60 -reducing,
0,
7)
@ -404,7 +421,7 @@ def draw(outlayer, win, path, back="story_editor"):
UI_elements.roundrect(layer, win,
50,
17,
(width - 60 )*fraction,
(width - 60 -reducing)*fraction,
0,
7)

View file

@ -46,8 +46,53 @@ from studio import studio_dialogs
from studio import schedule
from studio import history
def datetip(win, date):
# Function that outputs basic analytics about a given date
# in text form
# TODO: This function is in a prototype stage. Meaning it's
# not translated to multiple languages. This should be fixed.
# See settings/talk.py file.
text = date
try:
data = win.analytics["dates"][date]
# Expected
startdate = win.analytics["startdate"]
deadline = win.analytics["deadline"]
duration = win.analytics["duration"]
new_date_format = "%Y/%m/%d"
sd = datetime.datetime.strptime(startdate, new_date_format)
nd = datetime.datetime.strptime(date , new_date_format)
dn = nd - sd
daysin = int(dn.days)
expected = round(100 / duration * daysin, 2)
text = text +"\n\nExpected: "+str(expected)+"%"
# Actual
frac = round(data.get("fractions", {}).get("project")*100, 2)
text = text +"\nActual: "+str(frac)+"%"
# Productivity
productivity = int(round(frac - expected+100))
text = text +"\n\nProductivity: "+str(productivity)+"%"
except Exception as e:
pass
return text
def layer(win):
# This is very important. I makes live easier. LOL.
win.current["shot_left_side_scroll_please_work_omg_wtf"] = True
# Making the layer
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
@ -151,7 +196,9 @@ def layer(win):
25,
win.current["w"]/2-80,
20,
10)
10,
tip=str(round(projectdone*100, 1))+"%")
@ -180,7 +227,8 @@ def layer(win):
65,
win.current["w"]/2-80,
20,
10)
10,
tip=str(round(timepassed*100, 1))+"%")
# Timepassed
UI_color.set(layer, win, "progress_time")
@ -195,22 +243,25 @@ def layer(win):
# Icon
UI_elements.image(layer, win, "settings/themes/"\
+win.settings["Theme"]+"/icons/scene.png",
+win.settings["Theme"]+"/icons/shot.png",
win.current["w"]/4+10,
95,
40,
40)
UI_color.set(layer, win, "progress_background")
UI_color.set(layer, win, "shot_5")
UI_elements.roundrect(layer, win,
win.current["w"]/4+60,
105,
win.current["w"]/2-80,
20,
10)
10,
tip=str(round(rnddone*100, 1))+"%",
fill=False)
layer.stroke()
# Scenes
UI_color.set(layer, win, "node_videofile")
UI_color.set(layer, win, "shot_5")
UI_elements.roundrect(layer, win,
win.current["w"]/4+60,
105,
@ -228,16 +279,19 @@ def layer(win):
40,
40)
UI_color.set(layer, win, "progress_background")
UI_color.set(layer, win, "shot_1")
UI_elements.roundrect(layer, win,
win.current["w"]/4+60,
145,
win.current["w"]/4-80,
20,
10)
10,
tip=str(round(chrdone*100, 1))+"%",
fill=False)
layer.stroke()
# progress
UI_color.set(layer, win, "node_asset")
UI_color.set(layer, win, "shot_1")
UI_elements.roundrect(layer, win,
win.current["w"]/4+60,
145,
@ -255,16 +309,19 @@ def layer(win):
40,
40)
UI_color.set(layer, win, "progress_background")
UI_color.set(layer, win, "shot_2")
UI_elements.roundrect(layer, win,
win.current["w"]/2+60,
145,
win.current["w"]/4-80,
20,
10)
10,
tip=str(round(vehdone*100, 1))+"%",
fill=False)
layer.stroke()
# progress
UI_color.set(layer, win, "node_imagefile")
UI_color.set(layer, win, "shot_2")
UI_elements.roundrect(layer, win,
win.current["w"]/2+60,
145,
@ -282,16 +339,19 @@ def layer(win):
40,
40)
UI_color.set(layer, win, "progress_background")
UI_color.set(layer, win, "shot_3")
UI_elements.roundrect(layer, win,
win.current["w"]/4+60,
185,
win.current["w"]/4-80,
20,
10)
10,
tip=str(round(locdone*100, 1))+"%",
fill=False)
layer.stroke()
# progress
UI_color.set(layer, win, "node_blendfile")
UI_color.set(layer, win, "shot_3")
UI_elements.roundrect(layer, win,
win.current["w"]/4+60,
185,
@ -309,16 +369,19 @@ def layer(win):
40,
40)
UI_color.set(layer, win, "progress_background")
UI_color.set(layer, win, "shot_4")
UI_elements.roundrect(layer, win,
win.current["w"]/2+60,
185,
win.current["w"]/4-80,
20,
10)
10,
tip=str(round(objdone*100, 1))+"%",
fill=False)
layer.stroke()
# progress
UI_color.set(layer, win, "node_badfile")
UI_color.set(layer, win, "shot_4")
UI_elements.roundrect(layer, win,
win.current["w"]/2+60,
185,
@ -347,7 +410,7 @@ def layer(win):
# Let's make a mode selector.
if "analytics_middle_graph_mode" not in win.current:
win.current["analytics_middle_graph_mode"] = "pulse"
win.current["analytics_middle_graph_mode"] = "linear"
for num, thing in enumerate(["linear", "analytics", "pulse"]): # By icons
@ -415,12 +478,12 @@ def layer(win):
if "analytics_middle_graph_switch" not in win.current:
win.current["analytics_middle_graph_switch"] = {
"project":[True,"analytics", "progress_active"],
"checklist":[True,"checklist", "darker_parts"],
"rnd":[True,"scene", "node_videofile"],
"chr":[True,"chr", "node_asset"],
"veh":[True,"veh", "node_imagefile"], # Name in data : [ Active, Icon name, color ]
"loc":[True,"loc", "node_blendfile"],
"obj":[True,"obj", "node_badfile"]
"checklist":[True,"checklist", "node_videofile"],
"rnd":[True,"shot", "shot_5"],
"chr":[True,"chr", "shot_1"],
"veh":[True,"veh", "shot_2"], # Name in data : [ Active, Icon name, color ]
"loc":[True,"loc", "shot_3"],
"obj":[True,"obj", "shot_4"]
}
cat = win.current["analytics_middle_graph_switch"]
@ -434,9 +497,11 @@ def layer(win):
UI_elements.roundrect(layer, win,
win.current["w"]/4+160+(40*num),
225,
38,
40,
40,
10)
10,
fill=False)
layer.stroke()
def do():
cat[thing][0] = not cat[thing][0]
@ -445,7 +510,7 @@ def layer(win):
UI_elements.roundrect(layer, win,
win.current["w"]/4+160+(40*num),
225,
40,
38,
40,
10,
do,
@ -466,6 +531,8 @@ def layer(win):
# Now let's make a layer.
# CURRENT DATE
today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
if "graph_cashe" not in win.current:
@ -483,7 +550,7 @@ def layer(win):
#node.fill()
# helping line
UI_color.set(node, win, "progress_background")
UI_color.set(node, win, "progress_time")
if mode == "analytics":
@ -503,6 +570,7 @@ def layer(win):
node.stroke()
todayX = 0
for num, thing in enumerate(reversed(cat)):
@ -530,6 +598,9 @@ def layer(win):
graphX = width / duration * dn
if date == today:
todayX = graphX
# Let's calculate the Y position of a given part on a graph
if "fractions" in dates[date]:
@ -555,7 +626,57 @@ def layer(win):
node.stroke()
# Today
UI_color.set(node, win, "button_clicked")
node.move_to(todayX, 0)
node.line_to(todayX, height)
node.stroke()
win.current["graph_cashe"] = graphsurface
# Dynamic elements of the graph!
# I sense a possible bug here, since I will draw these on top
# of a prebaked image. And something sometimes might not align
# properly. I don't know how to deal with it quite yet, perhaps
# you can try fixing the issue. LOL.
# Bottom Graph position on the top graph.
try:
posX = width / (duration*50) * win.scroll["days"]
posX2 = (width / (duration*50) * (win.scroll["days"]+width))-posX
except:
posX = 0
posX2 = 20
UI_color.set(layer, win, "dark_overdrop")
UI_elements.roundrect(layer, win,
x-posX,
y,
posX2,
height,
5,
fill=True)
layer.stroke()
# Mouse drag thingy
if x < win.current["mx"] < x+width\
and y < win.current["my"] < y+height:
if win.current["LMB"]:
win.scroll["days"] = 0- (( win.current["mx"] - x ) / width * (duration*50)) + (width/2)
sd = datetime.datetime.strptime(startdate, new_date_format)
daysin = int(round( duration / width * (x-win.current["mx"])))*-1
td = datetime.timedelta(days=daysin)
hoverdate = sd + td
hoverdate = hoverdate.strftime(new_date_format)
UI_elements.tooltip(win, datetip(win, hoverdate))
UI_color.set(layer, win, "progress_background")
layer.move_to(win.current["mx"], y)
layer.line_to(win.current["mx"], y+height)
layer.stroke()
# Outputting the layer
layer.set_source_surface(win.current["graph_cashe"], x, y)
layer.paint()
@ -617,8 +738,6 @@ def layer(win):
do,
button)
# CURRENT DATE
today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
UI_elements.text(layer, win, "current_date_setting",
x+100,
@ -678,7 +797,8 @@ def layer(win):
prevyear = [startdate.split("/")[0], win.scroll["days"]]
prevmonth = [startdate.split("/")[1], win.scroll["days"]]
prevday = "1997/07/30"
pfrac = {}
for doffset in range(duration+1): # FOR ALL DAYS. NO MATTER IF THEY ARE IN DATA
@ -858,7 +978,8 @@ def layer(win):
10,
button=do,
offset=[x,y],
fill=False)
fill=False,
tip=datetip(win, theday))
node.stroke()
##################### BOTTOM GRAPH #######################
@ -873,28 +994,72 @@ def layer(win):
# need to be able to navigate with in the bottom graph.
# So instead I'm going to redo the graph, but since we
# are re-doing it. I gonna make a slightly different design.
# It will show the same exact data. But drawn with a bit more
# beauty, compared to the top graph.
# are re-doing it. I orignally wanted to do a different
# design. But it ended up looking confusing. It needs lines!
# Roundrects will not do.
for num, thing in enumerate(reversed(cat)):
if cat[thing][0]:
UI_color.set(node, win, cat[thing][2])
try:
fracs = win.analytics["dates"][theday]["fractions"]
gfraction = fracs[thing]
# For now I will implement only Linear mode
# other modes will come later
graphY = ((height-80) - (height-80) * gfraction)+60
UI_elements.roundrect(node, win,
8+current_X+win.scroll["days"],
graphY,
35,
8,
5)
except:
pass
sd = datetime.datetime.strptime(startdate, new_date_format)
nd = datetime.datetime.strptime(theday , new_date_format)
dn = nd - sd
dn = int(dn.days)
fracs = win.analytics["dates"][theday]["fractions"]
Pfracs = win.analytics["dates"][prevday]["fractions"]
gfraction = fracs[thing]
if mode == "linear":
graphY = ((height-80) - (height-80) * gfraction)+60
elif mode == "analytics":
tfraction = dn / duration
gfraction = gfraction / tfraction / 2
graphY = ((height-80) - (height-80) * gfraction)+60
else:
try:
gfraction = fracs[thing]
gfraction = gfraction - Pfracs[thing]
except:
gfraction = 0
graphY = ((height-80) - (height-80) * gfraction - (height-80) / 2)+60
PgraphY = pfrac.get(thing, graphY)
pfrac[thing] = graphY
node.move_to(current_X+win.scroll["days"]-25,
PgraphY)
node.line_to(current_X+win.scroll["days"]+25,
graphY)
node.stroke()
except Exception as e:
if theday < today and theday not in win.analytics["dates"]:
UI_color.set(node, win, "node_badfile")
UI_elements.roundrect(node, win,
5+current_X+win.scroll["days"],
67,
40,
height-67,
10,
fill=False)
node.stroke()
@ -903,6 +1068,28 @@ def layer(win):
# Now here I want to draw the representations of scheduled
# tasks that are inside
# Icons of what was done at the day
icons_stuff = {"assets":"obj",
"scenes":"shot",
"files":"checklist"}
icons = []
for t in icons_stuff:
if t in win.analytics["dates"].get(theday, {}) and t != "assets":
icons.append(icons_stuff[t])
elif t in win.analytics["dates"].get(theday, {}):
for at in ["chr", "obj", "loc", "veh"]:
for stuff in win.analytics["dates"].get(theday, {})[t]:
if at in stuff and at not in icons:
icons.append(at)
for nicon, icon in enumerate(icons):
UI_elements.image(node, win, "settings/themes/"\
+win.settings["Theme"]+"/icons/"+icon+".png",
6+current_X+win.scroll["days"],
height-(50*nicon)-50,
40,
40)
sch = []
if theday in win.analytics["dates"]:
date = win.analytics["dates"][theday]
@ -938,8 +1125,12 @@ def layer(win):
5)
current_X = current_X + 50
prevday = theday
UI_color.set(node, win, "dark_overdrop")
UI_elements.roundrect(node, win,

View file

@ -268,6 +268,12 @@ def pmdrawing(pmdrawing, main_layer, win):
# Current frame (for animations and things like this)
win.current["frame"] += 1
if win.current["frame"] == 10:
win.cur = "/set"
win.url = "analytics"
if not "scale" in win.settings:
settings.write("scale", 1) # Writing to file
win.settings = settings.load_all()

View file

@ -151,7 +151,7 @@ def layer(win):
slist.append([date, item, schedules[date][item]])
# Now that we have our list we can start paring it the same way as in the
# Now that we have our list we can start parsing it the same way as in the
# scheduling. Only removing some unnesesary stuff.
foundtask = False
taskname = ""