📣 An issue occured with the embedded container registry on October 25 2021, between 10:30 and 12:10 (UTC+2). Any persisting issues should be reported to CC-IN2P3 Support. 🐛

Commit 7610297f authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Redesign the metric2d controller and views.

parent 7f0ae64a
......@@ -6,12 +6,10 @@ import traceback
from datetime import datetime
from matplotlib.figure import Figure
from plugin_dbui import get_id
from plugin_event import (Graph,
List,
Metric2D,
ReportException,
Source)
from plugin_event import ReportException
MSG = T("%s entry(ies) modified in the history table. "
"DO NOT FORGET TO MODIFIED CONFIGURATION OF REPORT(s).")
......@@ -30,6 +28,8 @@ def grid():
the data displayed in the grid.
"""
from plugin_event import List
try:
report = List(request.vars.id_list)
store = report.get_store_configuration()
......@@ -39,7 +39,6 @@ def grid():
except (IndexError, ReportException, TypeError, ValueError):
return CODE(traceback.format_exc()).xml()
response.view = "plugin_event/grid.html"
return dict(cfg_store=store, grid=grid, title=title)
......@@ -56,36 +55,42 @@ def metric2d():
the graph.
"""
extension = request.extension
import base64
import io
import os
from uuid import uuid4
from plugin_event import Graph, Metric2D, mplstyle
try:
report = Metric2D(request.vars.id_metric2d)
graph = Graph(report)
title = report.get_title()
mplstyle()
fig = Figure()
Graph(report, fig)
extension = request.extension
if extension == "html":
store = report.get_store_configuration()
grid = report.get_grid_configuration()
if graph.ax is not None:
img = graph.to_svg()
response.view = "plugin_event/grid_and_graph.html"
return dict(cfg_store=store, grid=grid, img=img, title=title)
buf = io.BytesIO()
fig.savefig(buf, format="svg")
data = base64.b64encode(buf.getbuffer()).decode("ascii")
title = report.get_title()
else:
response.view = "plugin_event/grid.html"
return dict(cfg_store=store, grid=grid, title=title)
return dict(cfg_store=store, grid=grid, img=data, title=title)
elif extension == "pdf":
data = graph.to_pdf()
response.view = "plugin_event/graph.pdf"
return dict(data=data)
else:
fn = str(uuid4())
pfn = os.path.join("/tmp", f"{fn}.{extension}")
elif extension == "png":
data = graph.to_png()
response.view = "plugin_event/graph.png"
return dict(data=data)
with open(pfn, "wb") as fi:
fig.savefig(fi, format=extension)
return response.stream(pfn)
except (IndexError, ReportException, TypeError, ValueError):
return CODE(traceback.format_exc()).xml()
......@@ -96,6 +101,8 @@ def source():
Values send by the selector are used to filter the content of the source.
"""
from plugin_event import Source
try:
report = Source(request.vars.source)
store = report.get_store_configuration()
......
......@@ -41,9 +41,9 @@ from .event import (Event,
from .matplotlib_tools import (bicolor,
create_pdf,
header_footer,
mplstyle,
plot_references,
plot_values,
style,
table_only,
ticks_and_labels,
xticks_and_labels)
......
......@@ -75,6 +75,35 @@ def header_footer(fig, title, timestamp=False):
fig.text(0.94, 0.04, fig.number, fontsize=10, horizontalalignment='right')
def mplstyle():
"""Define the matplotlib style, namely font size, line width, etc.
"""
mpl.rcParams['legend.fontsize'] = 7
mpl.rcParams["grid.alpha"] = 0.5
mpl.rcParams["grid.linestyle"] = "dotted"
mpl.rcParams["xtick.direction"] = "in"
mpl.rcParams["xtick.top"] = True
mpl.rcParams["xtick.bottom"] = True
mpl.rcParams["xtick.major.size"] = 8
mpl.rcParams["xtick.minor.size"] = 4
mpl.rcParams["xtick.labelsize"] = 8
mpl.rcParams["ytick.direction"] = "in"
mpl.rcParams["ytick.left"] = True
mpl.rcParams["ytick.right"] = True
mpl.rcParams["ytick.major.size"] = 8
mpl.rcParams["ytick.minor.size"] = 4
mpl.rcParams["ytick.labelsize"] = 8
mpl.rcParams['xtick.major.size'] = 8
mpl.rcParams['xtick.minor.size'] = 4
mpl.rcParams['ytick.major.size'] = 8
mpl.rcParams['ytick.minor.size'] = 4
def plot_references(ax, lines, values, xpos, stacked=False):
"""Plot reference markers.
......@@ -174,23 +203,6 @@ def plot_values(ax,
ax.text(i, y, fmt % value, **default)
def style():
"""Define the matplotlib style, namely font size, line width, etc.
"""
mpl.rcParams['axes.labelsize'] = 9
mpl.rcParams['figure.figsize'] = (29.7 / 2.54, 21 / 2.54)
mpl.rcParams['figure.subplot.top'] = 0.85
mpl.rcParams['legend.fontsize'] = 7
mpl.rcParams['lines.linewidth'] = 1.
mpl.rcParams['xtick.major.size'] = 8
mpl.rcParams['xtick.minor.size'] = 4
mpl.rcParams['xtick.labelsize'] = 8
mpl.rcParams['ytick.major.size'] = 8
mpl.rcParams['ytick.minor.size'] = 4
mpl.rcParams['ytick.labelsize'] = 8
def table_only(ax, mytable, fontsize=10, cellheight=0.10):
"""Show only the table
......
"""report_tools module
"""
import base64
import io
import json
import matplotlib as mpl
import pandas as pd
......@@ -185,28 +183,16 @@ class Graph(object):
representations of the data are possible: plot, histogram, bar charts,
error charts, scatter plots, *etc*.
Attributes:
ax (matplotlib.axes or None)
Args:
metric2d (Metrics2D2): the data to be plotted.
config (gluon.storage.Storage):
the configuration for the graph.
This is a dictionary with the keyword arguments of the
``pandasDataFrame.plot`` method.
backend (str):
the name of the matplotlib back-end uses to produce figure.
The X11 back end is not needed when running on a server.
In addition Tkinter crash with the message "out of stack space"
when the 2nd plot is generated. The documentation recommend to
limit the matplotlib back end to ``Agg`` which is tuned to render
high quality PNG image. But, it is also design to render PDF
and SVG image without the X11 interface.
metric2d (Metrics2D2):
the data to be plotted.
figure (matplotlib.figure.Figure):
the figure housing the plot.
"""
def __init__(self, metric2d, backend="Agg"):
def __init__(self, metric2d, figure=None):
# configuration
config = metric2d.config
......@@ -237,35 +223,8 @@ class Graph(object):
else:
config_graph["ylim"] = (int(el) for el in ylim.split(","))
# setup the matplotlib style
mpl.rcParams['legend.fontsize'] = 7
mpl.rcParams["grid.alpha"] = 0.5
mpl.rcParams["grid.linestyle"] = "dotted"
mpl.rcParams["xtick.direction"] = "in"
mpl.rcParams["xtick.top"] = True
mpl.rcParams["xtick.bottom"] = True
mpl.rcParams["xtick.major.size"] = 8
mpl.rcParams["xtick.minor.size"] = 4
mpl.rcParams["xtick.labelsize"] = 8
mpl.rcParams["ytick.direction"] = "in"
mpl.rcParams["ytick.left"] = True
mpl.rcParams["ytick.right"] = True
mpl.rcParams["ytick.major.size"] = 8
mpl.rcParams["ytick.minor.size"] = 4
mpl.rcParams["ytick.labelsize"] = 8
mpl.rcParams['xtick.major.size'] = 8
mpl.rcParams['xtick.minor.size'] = 4
mpl.rcParams['ytick.major.size'] = 8
mpl.rcParams['ytick.minor.size'] = 4
# create the figure and subplots
self.fig = fig = Figure()
self.ax = ax = fig.subplots(nrows=1, ncols=1)
config_graph["ax"] = ax
# create the subplot
config_graph["ax"] = figure.subplots(nrows=1, ncols=1)
# select the tool to render the plot
if kind in ("bar", "barh"):
......@@ -385,52 +344,6 @@ class Graph(object):
return ax
def _savefig(self, fmt):
"""Save the figure as a string.
Args:
fmt (str): possible values are pdf, png and svg.
Returns:
bytes string
"""
if self.ax is None:
return ""
buf = io.BytesIO()
self.fig.savefig(buf, format=fmt)
data = base64.b64encode(buf.getbuffer()).decode("ascii")
return data
def to_pdf(self):
"""Encode the graph using the PDF format
Returns:
str:
"""
return self._savefig("pdf")
def to_png(self):
"""Encode the graph using the PNG format.
Returns:
str:
"""
return self._savefig("png")
def to_svg(self):
"""Encode the graph using the SVG format.
Returns:
str:
"""
return self._savefig("svg")
class List(BaseReport):
"""Generate the list and related configurations for ``Ext.grid.Panel``
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment