Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
Kadi4
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Lucía Elizo Gómez
Kadi4
Commits
c0b5a635
Commit
c0b5a635
authored
Jun 03, 2026
by
Lucía Elizo Gómez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Plugin comparar
parent
9c0758dd
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
573 additions
and
0 deletions
+573
-0
kadi_plugin_comparar/build/lib/kadi_plugin_comparar/__init__.py
+1
-0
kadi_plugin_comparar/build/lib/kadi_plugin_comparar/plugin.py
+148
-0
kadi_plugin_comparar/comparar.egg-info/PKG-INFO
+6
-0
kadi_plugin_comparar/comparar.egg-info/SOURCES.txt
+12
-0
kadi_plugin_comparar/comparar.egg-info/dependency_links.txt
+1
-0
kadi_plugin_comparar/comparar.egg-info/entry_points.txt
+2
-0
kadi_plugin_comparar/comparar.egg-info/requires.txt
+1
-0
kadi_plugin_comparar/comparar.egg-info/top_level.txt
+1
-0
kadi_plugin_comparar/kadi_plugin_comparar/__init__.py
+1
-0
kadi_plugin_comparar/kadi_plugin_comparar/__pycache__/__init__.cpython-312.pyc
+0
-0
kadi_plugin_comparar/kadi_plugin_comparar/__pycache__/plugin.cpython-312.pyc
+0
-0
kadi_plugin_comparar/kadi_plugin_comparar/plugin.py
+158
-0
kadi_plugin_comparar/kadi_plugin_comparar/templates/comparar/comparar.html
+217
-0
kadi_plugin_comparar/pyproject.toml
+10
-0
kadi_plugin_comparar/setup.py
+15
-0
No files found.
kadi_plugin_comparar/build/lib/kadi_plugin_comparar/__init__.py
0 → 100644
View file @
c0b5a635
__version__
=
"0.1.0"
kadi_plugin_comparar/build/lib/kadi_plugin_comparar/plugin.py
0 → 100644
View file @
c0b5a635
"""
Kadi4Mat plugin: Comparar sesiones
------------------------------------
Permite comparar métricas de varios records de sesión de impresión 3D
mediante gráficas interactivas.
Hooks:
- kadi_get_blueprints → página /comparar y API
- kadi_get_resource_overview_templates → botón en cada record
- kadi_post_app_initialization → log de arranque
Endpoints:
GET /comparar/ → página principal con gráficas
GET /api/comparar/record/<id> → devuelve métricas de un record
GET /api/comparar/buscar?q=texto → busca records por título
"""
from
flask
import
request
,
render_template
from
kadi.lib.api.blueprint
import
bp
as
api_bp
from
kadi.lib.api.core
import
json_response
,
json_error_response
from
kadi.lib.plugins.core
import
PluginBlueprint
from
kadi.plugins
import
hookimpl
PLUGIN_NAME
=
"comparar"
# ── Blueprint ─────────────────────────────────────────────────────────────────
plugin_bp
=
PluginBlueprint
(
PLUGIN_NAME
,
__name__
,
url_prefix
=
"/comparar"
,
template_folder
=
"templates"
,
)
# ── Métricas a comparar ───────────────────────────────────────────────────────
METRICAS_COMPARAR
=
[
(
"hotend_temp_max_c"
,
"Hotend temp. máx (°C)"
),
(
"hotend_temp_media_c"
,
"Hotend temp. media (°C)"
),
(
"cama_temp_max_c"
,
"Cama temp. máx (°C)"
),
(
"duracion_impresion_s"
,
"Duración impresión (s)"
),
(
"filamento_usado_mm"
,
"Filamento usado (mm)"
),
(
"cpu_media_pct"
,
"CPU media (
%
)"
),
(
"pi_temp_max_c"
,
"Temp. Pi máx (°C)"
),
]
# ── Helpers ───────────────────────────────────────────────────────────────────
def
_extraer_metricas
(
record
)
->
dict
:
"""Extrae las métricas relevantes de los extras de un record de Kadi4Mat."""
resultado
=
{
"id"
:
record
.
id
,
"title"
:
record
.
title
,
}
extras
=
{
e
.
key
:
e
.
value
for
e
in
(
record
.
extras
or
[])}
for
key
,
_
in
METRICAS_COMPARAR
:
val
=
extras
.
get
(
key
)
try
:
resultado
[
key
]
=
float
(
val
)
if
val
is
not
None
else
None
except
(
ValueError
,
TypeError
):
resultado
[
key
]
=
None
return
resultado
# ── Endpoints ─────────────────────────────────────────────────────────────────
@plugin_bp.get
(
"/"
)
def
pagina_comparar
():
"""Página principal con las gráficas comparativas."""
return
render_template
(
"comparar/comparar.html"
,
metricas
=
METRICAS_COMPARAR
)
@api_bp.get
(
"/comparar/record/<int:record_id>"
)
def
get_record_metricas
(
record_id
):
"""Devuelve las métricas de un record para usarlas en las gráficas."""
from
kadi.modules.records.models
import
Record
record
=
Record
.
query
.
get
(
record_id
)
if
record
is
None
:
return
json_error_response
(
404
,
description
=
"Record no encontrado."
)
return
json_response
(
200
,
_extraer_metricas
(
record
))
@api_bp.get
(
"/comparar/buscar"
)
def
buscar_records
():
"""Busca records por título para el autocompletado. ?q=texto"""
from
kadi.modules.records.models
import
Record
q
=
request
.
args
.
get
(
"q"
,
""
)
.
strip
()
if
not
q
:
return
json_response
(
200
,
{
"items"
:
[]})
records
=
(
Record
.
query
.
filter
(
Record
.
title
.
ilike
(
f
"
%
{q}
%
"
))
.
limit
(
10
)
.
all
()
)
items
=
[{
"id"
:
r
.
id
,
"title"
:
r
.
title
,
"identifier"
:
r
.
identifier
}
for
r
in
records
]
return
json_response
(
200
,
{
"items"
:
items
})
# ── Botón en la página de cada record ────────────────────────────────────────
BOTON_TEMPLATE
=
"""
<div style="margin-top: 1rem;">
<a href="/comparar/?add={{ resource.id }}"
style="
display: inline-block;
padding: 0.4rem 1rem;
background: #1976d2;
color: white;
border-radius: 4px;
text-decoration: none;
font-size: 0.9rem;
">
📊 Añadir a comparación
</a>
</div>
"""
# ── Hooks ─────────────────────────────────────────────────────────────────────
@hookimpl
def
kadi_get_blueprints
():
return
plugin_bp
@hookimpl
def
kadi_get_resource_overview_templates
(
resource
):
"""Añade el botón en la página de cada record."""
from
flask
import
render_template_string
from
kadi.modules.records.models
import
Record
if
not
isinstance
(
resource
,
Record
):
return
None
return
render_template_string
(
BOTON_TEMPLATE
,
resource
=
resource
)
@hookimpl
def
kadi_post_app_initialization
(
app
):
app
.
logger
.
info
(
"comparar: plugin activo. "
"Página: GET /comparar/ | "
"API: GET /api/comparar/record/<id>"
)
kadi_plugin_comparar/comparar.egg-info/PKG-INFO
0 → 100644
View file @
c0b5a635
Metadata-Version: 2.4
Name: comparar
Version: 0.1.0
Summary: Plugin de comparación de sesiones de impresión 3D para Kadi4Mat
Requires-Python: >=3.10
Requires-Dist: kadi
kadi_plugin_comparar/comparar.egg-info/SOURCES.txt
0 → 100644
View file @
c0b5a635
pyproject.toml
setup.py
comparar.egg-info/PKG-INFO
comparar.egg-info/SOURCES.txt
comparar.egg-info/dependency_links.txt
comparar.egg-info/entry_points.txt
comparar.egg-info/requires.txt
comparar.egg-info/top_level.txt
kadi_plugin_comparar/__init__.py
kadi_plugin_comparar/plugin.py
kadi_plugin_comparar/templates/comparar/comparar.html
\ No newline at end of file
kadi_plugin_comparar/comparar.egg-info/dependency_links.txt
0 → 100644
View file @
c0b5a635
kadi_plugin_comparar/comparar.egg-info/entry_points.txt
0 → 100644
View file @
c0b5a635
[kadi_plugins]
comparar = kadi_plugin_comparar.plugin
kadi_plugin_comparar/comparar.egg-info/requires.txt
0 → 100644
View file @
c0b5a635
kadi
kadi_plugin_comparar/comparar.egg-info/top_level.txt
0 → 100644
View file @
c0b5a635
kadi_plugin_comparar
kadi_plugin_comparar/kadi_plugin_comparar/__init__.py
0 → 100644
View file @
c0b5a635
__version__
=
"0.1.0"
kadi_plugin_comparar/kadi_plugin_comparar/__pycache__/__init__.cpython-312.pyc
0 → 100644
View file @
c0b5a635
File added
kadi_plugin_comparar/kadi_plugin_comparar/__pycache__/plugin.cpython-312.pyc
0 → 100644
View file @
c0b5a635
File added
kadi_plugin_comparar/kadi_plugin_comparar/plugin.py
0 → 100644
View file @
c0b5a635
"""
Kadi4Mat plugin: Comparar sesiones
------------------------------------
Permite comparar metricas de varios records de sesion de impresión 3D
mediante gráficas interactivas.
Hooks:
- kadi_get_blueprints → página /comparar y API
- kadi_get_resource_overview_templates → botón en cada record
- kadi_post_app_initialization → log de arranque
Endpoints:
GET /comparar/ → página principal con gráficas
GET /api/comparar/record/<id> → devuelve métricas de un record
GET /api/comparar/buscar?q=texto → busca records por título
"""
from
flask
import
request
,
render_template
from
kadi.lib.api.blueprint
import
bp
as
api_bp
from
kadi.lib.api.core
import
json_response
,
json_error_response
from
kadi.lib.plugins.core
import
PluginBlueprint
from
kadi.plugins
import
hookimpl
PLUGIN_NAME
=
"comparar"
# ── Blueprint ─────────────────────────────────────────────────────────────────
plugin_bp
=
PluginBlueprint
(
PLUGIN_NAME
,
__name__
,
url_prefix
=
"/comparar"
,
template_folder
=
"templates"
,
)
# ── Métricas a comparar ───────────────────────────────────────────────────────
METRICAS_COMPARAR
=
[
(
"hotend_temp_max_c"
,
"Hotend temp. máx (°C)"
),
(
"hotend_temp_media_c"
,
"Hotend temp. media (°C)"
),
(
"cama_temp_max_c"
,
"Cama temp. máx (°C)"
),
(
"duracion_impresion_s"
,
"Duración impresión (s)"
),
(
"filamento_usado_mm"
,
"Filamento usado (mm)"
),
(
"cpu_media_pct"
,
"CPU media (
%
)"
),
(
"pi_temp_max_c"
,
"Temp. Pi máx (°C)"
),
]
# ── Helpers ───────────────────────────────────────────────────────────────────
def
_extraer_metricas
(
record
)
->
dict
:
"""Extrae las métricas relevantes de los extras de un record de Kadi4Mat."""
resultado
=
{
"id"
:
record
.
id
,
"title"
:
record
.
title
,
}
extras
=
{
e
[
"key"
]:
e
[
"value"
]
for
e
in
(
record
.
extras
or
[])}
for
key
,
_
in
METRICAS_COMPARAR
:
val
=
extras
.
get
(
key
)
try
:
resultado
[
key
]
=
float
(
val
)
if
val
is
not
None
else
None
except
(
ValueError
,
TypeError
):
resultado
[
key
]
=
None
return
resultado
# ── Endpoints ─────────────────────────────────────────────────────────────────
@plugin_bp.get
(
"/"
)
def
pagina_comparar
():
"""Página principal con las gráficas comparativas."""
return
render_template
(
"comparar/comparar.html"
,
metricas
=
METRICAS_COMPARAR
)
@api_bp.get
(
"/comparar/record/<int:record_id>"
)
def
get_record_metricas
(
record_id
):
"""Devuelve las métricas de un record para usarlas en las gráficas."""
from
kadi.modules.records.models
import
Record
record
=
Record
.
query
.
get
(
record_id
)
if
record
is
None
:
return
json_error_response
(
404
,
description
=
"Record no encontrado."
)
return
json_response
(
200
,
_extraer_metricas
(
record
))
@api_bp.get
(
"/comparar/buscar"
)
def
buscar_records
():
"""Busca records por título para el autocompletado. ?q=texto"""
from
kadi.modules.records.models
import
Record
q
=
request
.
args
.
get
(
"q"
,
""
)
.
strip
()
if
not
q
:
return
json_response
(
200
,
{
"items"
:
[]})
records
=
(
Record
.
query
.
filter
(
Record
.
title
.
ilike
(
f
"
%
{q}
%
"
))
.
limit
(
10
)
.
all
()
)
items
=
[{
"id"
:
r
.
id
,
"title"
:
r
.
title
,
"identifier"
:
r
.
identifier
}
for
r
in
records
]
return
json_response
(
200
,
{
"items"
:
items
})
# ── Botón en la página de cada record ────────────────────────────────────────
BOTON_TEMPLATE
=
"""
<div style="margin-bottom: 1rem;">
<a href="/comparar/?add={{ resource.id }}"
style="
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.4rem 1rem;
background: #2c3e50;
color: white;
border-radius: 4px;
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
">
📊 Añadir a comparación
</a>
</div>
"""
# ── Hooks ─────────────────────────────────────────────────────────────────────
@hookimpl
def
kadi_get_content_security_policies
():
"""Permite cargar Chart.js desde cdnjs y ejecutar scripts inline."""
return
{
"script-src"
:
"https://cdnjs.cloudflare.com"
,
}
@hookimpl
def
kadi_get_blueprints
():
return
plugin_bp
@hookimpl
def
kadi_get_resource_overview_templates
(
resource
):
"""Añade el botón en la página de cada record."""
from
flask
import
render_template_string
from
kadi.modules.records.models
import
Record
if
not
isinstance
(
resource
,
Record
):
return
None
return
render_template_string
(
BOTON_TEMPLATE
,
resource
=
resource
)
@hookimpl
def
kadi_post_app_initialization
(
app
):
app
.
logger
.
info
(
"comparar: plugin activo. "
"Página: GET /comparar/ | "
"API: GET /api/comparar/record/<id>"
)
kadi_plugin_comparar/kadi_plugin_comparar/templates/comparar/comparar.html
0 → 100644
View file @
c0b5a635
<!DOCTYPE html>
<html
lang=
"es"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Comparar sesiones — Kadi4Mat
</title>
<script
src=
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"
nonce=
"{{ csp_nonce() }}"
></script>
<style>
body
{
font-family
:
sans-serif
;
max-width
:
1100px
;
margin
:
2rem
auto
;
padding
:
0
1rem
;
color
:
#222
;
}
h1
{
font-size
:
1.6rem
;
margin-bottom
:
0.5rem
;
}
.buscador
{
display
:
flex
;
gap
:
0.5rem
;
margin-bottom
:
1rem
;
}
.buscador
input
{
flex
:
1
;
padding
:
0.5rem
;
border
:
1px
solid
#ccc
;
border-radius
:
4px
;
font-size
:
1rem
;
}
.buscador
button
{
padding
:
0.5rem
1.2rem
;
background
:
#1976d2
;
color
:
#fff
;
border
:
none
;
border-radius
:
4px
;
cursor
:
pointer
;
}
.sugerencias
{
border
:
1px
solid
#ccc
;
border-radius
:
4px
;
max-height
:
200px
;
overflow-y
:
auto
;
display
:
none
;
position
:
absolute
;
background
:
white
;
width
:
100%
;
z-index
:
10
;
}
.sugerencia
{
padding
:
0.5rem
1rem
;
cursor
:
pointer
;
}
.sugerencia
:hover
{
background
:
#f0f4ff
;
}
.chips
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
0.5rem
;
margin-bottom
:
1.5rem
;
}
.chip
{
background
:
#e3f0ff
;
border-radius
:
20px
;
padding
:
0.3rem
0.8rem
;
font-size
:
0.9rem
;
display
:
flex
;
align-items
:
center
;
gap
:
0.4rem
;
}
.chip
button
{
background
:
none
;
border
:
none
;
cursor
:
pointer
;
font-size
:
1rem
;
color
:
#555
;
}
.graficas
{
display
:
grid
;
grid-template-columns
:
1
fr
1
fr
;
gap
:
1.5rem
;
}
.grafica
{
background
:
#fafafa
;
border
:
1px
solid
#e0e0e0
;
border-radius
:
8px
;
padding
:
1rem
;
}
canvas
{
max-height
:
250px
;
}
.vacio
{
color
:
#888
;
font-style
:
italic
;
}
@media
(
max-width
:
700px
)
{
.graficas
{
grid-template-columns
:
1
fr
;
}
}
</style>
</head>
<body>
<h1>
📊 Comparar sesiones de impresión
</h1>
<button
id=
"btn-volver"
style=
"
display: inline-flex;
align-items: center;
gap: 0.4rem;
padding: 0.4rem 1rem;
background: #2c3e50;
color: white;
border-radius: 4px;
border: none;
cursor: pointer;
font-size: 0.875rem;
font-weight: 500;
margin-bottom: 1rem;
"
>
← Volver
</button>
<p
class=
"vacio"
id=
"ayuda"
>
Busca y añade records para comparar sus métricas.
</p>
<!-- Buscador -->
<div
class=
"buscador"
>
<div
style=
"position: relative; flex: 1;"
>
<input
id=
"input-buscar"
type=
"text"
placeholder=
"Buscar record por título..."
autocomplete=
"off"
>
<div
class=
"sugerencias"
id=
"sugerencias"
></div>
</div>
<button
id=
"btn-añadir-id"
>
Añadir por ID
</button>
</div>
<!-- Chips: records seleccionados -->
<div
class=
"chips"
id=
"chips"
></div>
<!-- Gráficas -->
<div
class=
"graficas"
id=
"graficas"
></div>
<script
nonce=
"{{ csp_nonce() }}"
>
// ── Estado ───────────────────────────────────────────────────────────────
const
records
=
{};
const
colores
=
[
"#1976d2"
,
"#e53935"
,
"#43a047"
,
"#fb8c00"
,
"#8e24aa"
,
"#00897b"
];
const
metricas
=
{{
metricas
|
tojson
}};
const
charts
=
{};
// ── Al cargar: leer ?add=ID de la URL ────────────────────────────────────
const
params
=
new
URLSearchParams
(
window
.
location
.
search
);
if
(
params
.
get
(
"add"
))
cargarRecord
(
parseInt
(
params
.
get
(
"add"
)));
// ── Buscador ──────────────────────────────────────────────────────────────
const
inputBuscar
=
document
.
getElementById
(
"input-buscar"
);
const
divSugerencias
=
document
.
getElementById
(
"sugerencias"
);
inputBuscar
.
addEventListener
(
"input"
,
async
()
=>
{
const
q
=
inputBuscar
.
value
.
trim
();
if
(
q
.
length
<
2
)
{
divSugerencias
.
style
.
display
=
"none"
;
return
;
}
const
res
=
await
fetch
(
`/api/comparar/buscar?q=
${
encodeURIComponent
(
q
)}
`
);
const
data
=
await
res
.
json
();
divSugerencias
.
innerHTML
=
""
;
if
(
!
data
.
items
.
length
)
{
divSugerencias
.
style
.
display
=
"none"
;
return
;
}
data
.
items
.
forEach
(
r
=>
{
const
div
=
document
.
createElement
(
"div"
);
div
.
className
=
"sugerencia"
;
div
.
textContent
=
`
${
r
.
title
}
(ID:
${
r
.
id
}
)`
;
div
.
onclick
=
()
=>
{
cargarRecord
(
r
.
id
);
inputBuscar
.
value
=
""
;
divSugerencias
.
style
.
display
=
"none"
;
};
divSugerencias
.
appendChild
(
div
);
});
divSugerencias
.
style
.
display
=
"block"
;
});
document
.
getElementById
(
"btn-volver"
).
addEventListener
(
"click"
,
()
=>
{
history
.
back
();
});
document
.
getElementById
(
"btn-añadir-id"
).
addEventListener
(
"click"
,
a
ñ
adirPorId
);
document
.
addEventListener
(
"click"
,
e
=>
{
if
(
!
divSugerencias
.
contains
(
e
.
target
)
&&
e
.
target
!==
inputBuscar
)
divSugerencias
.
style
.
display
=
"none"
;
});
function
a
ñ
adirPorId
()
{
const
id
=
parseInt
(
prompt
(
"Introduce el ID del record:"
));
if
(
id
)
cargarRecord
(
id
);
}
// ── Cargar record desde la API ────────────────────────────────────────────
async
function
cargarRecord
(
id
)
{
if
(
records
[
id
])
return
;
const
res
=
await
fetch
(
`/api/comparar/record/
${
id
}
`
);
if
(
!
res
.
ok
)
{
alert
(
"Record no encontrado."
);
return
;
}
records
[
id
]
=
await
res
.
json
();
actualizarChips
();
actualizarGraficas
();
document
.
getElementById
(
"ayuda"
).
style
.
display
=
"none"
;
}
function
eliminarRecord
(
id
)
{
delete
records
[
id
];
actualizarChips
();
actualizarGraficas
();
if
(
!
Object
.
keys
(
records
).
length
)
document
.
getElementById
(
"ayuda"
).
style
.
display
=
""
;
}
// ── Chips ─────────────────────────────────────────────────────────────────
function
actualizarChips
()
{
const
div
=
document
.
getElementById
(
"chips"
);
div
.
innerHTML
=
""
;
Object
.
values
(
records
).
forEach
((
r
,
i
)
=>
{
const
chip
=
document
.
createElement
(
"div"
);
chip
.
className
=
"chip"
;
const
circulo
=
document
.
createElement
(
"span"
);
circulo
.
style
.
cssText
=
`width:12px;height:12px;border-radius:50%;background:
${
colores
[
i
%
colores
.
length
]}
;display:inline-block;`
;
const
texto
=
document
.
createElement
(
"span"
);
texto
.
textContent
=
r
.
title
;
const
boton
=
document
.
createElement
(
"button"
);
boton
.
textContent
=
"✕"
;
boton
.
title
=
"Quitar"
;
boton
.
addEventListener
(
"click"
,
()
=>
eliminarRecord
(
r
.
id
));
chip
.
appendChild
(
circulo
);
chip
.
appendChild
(
texto
);
chip
.
appendChild
(
boton
);
div
.
appendChild
(
chip
);
});
}
// ── Gráficas ──────────────────────────────────────────────────────────────
function
actualizarGraficas
()
{
const
ids
=
Object
.
keys
(
records
);
metricas
.
forEach
(([
key
,
label
])
=>
{
const
valores
=
ids
.
map
(
id
=>
records
[
id
][
key
]);
const
tieneValores
=
valores
.
some
(
v
=>
v
!==
null
&&
v
!==
undefined
);
if
(
!
tieneValores
)
{
if
(
charts
[
key
])
document
.
getElementById
(
`wrap-
${
key
}
`
).
style
.
display
=
"none"
;
return
;
}
if
(
!
charts
[
key
])
{
const
wrap
=
document
.
createElement
(
"div"
);
wrap
.
className
=
"grafica"
;
wrap
.
id
=
`wrap-
${
key
}
`
;
const
canvas
=
document
.
createElement
(
"canvas"
);
canvas
.
id
=
`chart-
${
key
}
`
;
wrap
.
appendChild
(
canvas
);
document
.
getElementById
(
"graficas"
).
appendChild
(
wrap
);
charts
[
key
]
=
new
Chart
(
canvas
,
{
type
:
"bar"
,
data
:
{
labels
:
[],
datasets
:
[]
},
options
:
{
responsive
:
true
,
plugins
:
{
legend
:
{
display
:
false
},
title
:
{
display
:
true
,
text
:
label
,
font
:
{
size
:
14
}
},
},
scales
:
{
y
:
{
beginAtZero
:
true
}
},
},
});
}
const
chart
=
charts
[
key
];
chart
.
data
.
labels
=
ids
.
map
(
id
=>
records
[
id
].
title
);
chart
.
data
.
datasets
=
[{
data
:
valores
.
map
(
v
=>
v
??
0
),
backgroundColor
:
ids
.
map
((
_
,
i
)
=>
colores
[
i
%
colores
.
length
]
+
"cc"
),
borderColor
:
ids
.
map
((
_
,
i
)
=>
colores
[
i
%
colores
.
length
]),
borderWidth
:
1
,
}];
chart
.
update
();
document
.
getElementById
(
`wrap-
${
key
}
`
).
style
.
display
=
""
;
});
}
</script>
</body>
</html>
kadi_plugin_comparar/pyproject.toml
0 → 100644
View file @
c0b5a635
[project]
name
=
"comparar"
version
=
"0.1.0"
description
=
"Plugin de comparación de sesiones de impresión 3D para Kadi4Mat"
requires-python
=
">=3.10"
dependencies
=
["kadi"]
[project.entry-points."kadi_plugins"]
comparar
=
"kadi_plugin_comparar.plugin"
kadi_plugin_comparar/setup.py
0 → 100644
View file @
c0b5a635
from
setuptools
import
setup
,
find_packages
setup
(
name
=
"comparar"
,
version
=
"0.1.0"
,
packages
=
find_packages
(),
package_data
=
{
"kadi_plugin_comparar"
:
[
"templates/**/*"
],
},
entry_points
=
{
"kadi_plugins"
:
[
"comparar = kadi_plugin_comparar.plugin"
,
],
},
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment