mirror of
https://github.com/Rushilwiz/drive-pipeline.git
synced 2025-04-09 15:00:20 -04:00
124 lines
4.6 KiB
Python
124 lines
4.6 KiB
Python
from django.db import models
|
|
from django.conf import settings
|
|
|
|
import io
|
|
from django.core import serializers
|
|
from django.templatetags.static import static
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
# Create your models here.
|
|
class Response(models.Model):
|
|
# user data
|
|
first_name = models.CharField("First Name", max_length=50)
|
|
last_name = models.CharField("Last Name", max_length=50)
|
|
email = models.EmailField("Email", max_length=254)
|
|
|
|
# scores
|
|
decision = models.PositiveIntegerField("Decision Making")
|
|
decision_it = models.PositiveIntegerField("Decision Making - IT")
|
|
decision_legal = models.PositiveIntegerField("Decision Making - Legal/Procurement")
|
|
resources = models.PositiveIntegerField("Resources")
|
|
impact = models.PositiveIntegerField("Impact")
|
|
velocity = models.PositiveIntegerField("Velocity")
|
|
expectations = models.PositiveIntegerField("Expectations")
|
|
|
|
# self.overall
|
|
overall = models.PositiveIntegerField("Overall Score")
|
|
|
|
results = models.ImageField("Results Image", blank=True, null=True)
|
|
results_pdf = models.ImageField("Results PDF", blank=True, null=True)
|
|
|
|
class Meta:
|
|
verbose_name = "Response"
|
|
verbose_name_plural = "Responses"
|
|
|
|
def __str__(self):
|
|
return f'{self.first_name} {self.last_name}\'s Response'
|
|
|
|
def save(self, *args, **kwargs):
|
|
self.results = f'{self.id}.png'
|
|
self.results_pdf = f'{self.id}.pdf'
|
|
super().save(*args, **kwargs)
|
|
fig, ax = plt.subplots(figsize=(8, 8))
|
|
|
|
height = list(serializers.serialize("python", [self])[0]['fields'].values())[3:-2]
|
|
print(f'height {height}')
|
|
bars = tuple([field.verbose_name for field in self._meta.get_fields()][4:-2])
|
|
y_pos = np.arange(len(bars))
|
|
|
|
for i, v in enumerate(height):
|
|
if v > 10:
|
|
ax.text(int(v) - 11,
|
|
i + 0.05,
|
|
f'{v}%',
|
|
color='white',
|
|
fontweight='bold',
|
|
fontsize=14)
|
|
else:
|
|
ax.text(int(v) + 2,
|
|
i + 0.05,
|
|
f'{v}%',
|
|
color='black',
|
|
fontweight='bold',
|
|
fontsize=14)
|
|
|
|
col = []
|
|
for val in height:
|
|
if val < 50:
|
|
col.append('#FF0000')
|
|
elif val <= 75:
|
|
col.append('#FFC000')
|
|
else:
|
|
col.append('#70AD47')
|
|
|
|
ax.barh(y_pos, height, align='center', color=col)
|
|
ax.set_xlim([0,100])
|
|
ax.set_yticks(y_pos)
|
|
ax.set_yticklabels(bars)
|
|
ax.invert_yaxis() # labels read top-to-bottom
|
|
ax.set_title('Breakdown by Section:')
|
|
|
|
buf = io.BytesIO()
|
|
plt.savefig(buf, format='png', bbox_inches='tight', transparent=False)
|
|
buf.seek(0)
|
|
im = Image.open(buf)
|
|
|
|
width, height = im.size
|
|
|
|
y_offset = 200
|
|
new_height = height + y_offset
|
|
result = Image.new(im.mode, (width, new_height), color=(255,255,255))
|
|
result.paste(im, (0, y_offset))
|
|
|
|
width, height = result.size
|
|
font_path = f"{str(settings.PROJECT_PATH)}{static('font/OpenSans-Regular.ttf')}"
|
|
|
|
font = ImageFont.truetype(font_path, size=25);
|
|
|
|
top_header = 'OVERALL PROGRESS:'
|
|
|
|
draw = ImageDraw.Draw(result)
|
|
draw.text(
|
|
((width-draw.textsize(top_header, font=font)[0])/2, draw.textsize(top_header)[1]), # Coordinates
|
|
top_header, # Text
|
|
(0, 0, 0), # Color
|
|
font=font
|
|
)
|
|
|
|
font = ImageFont.truetype(font_path, size=160);
|
|
|
|
draw.text(
|
|
(((width-draw.textsize(f'{self.overall}%', font=font)[0])/2), draw.textsize(top_header)[1]), # Coordinates
|
|
f'{self.overall}%', # Text
|
|
(255, 0, 0) if self.overall < 50 else (255, 192, 0) if self.overall <= 75 else (112, 173, 71), # Color
|
|
font=font
|
|
)
|
|
|
|
result.save(f'{settings.BASE_DIR}/media/{self.id}.png')
|
|
|
|
rgba = Image.open(f'{settings.BASE_DIR}/media/{self.id}.png')
|
|
rgb = Image.new('RGB', rgba.size, (255, 255, 255))
|
|
rgb.paste(rgba, mask=rgba.split()[3])
|
|
rgb.save(f'{settings.BASE_DIR}/media/{self.id}.pdf', 'PDF', resoultion=100.0) |