-- -- --- --- --- --- --- --- ------- ------- ------- |
"""
-- -- --- --- --- --- --- --- ------- ------- ------- |
Draw graph in HTML for a specific metric.
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
TODO: Add multiple lines for multiple files
-- -- --- --- --- --- --- --- ------- ------- ------- |
"""
-- -- --- --- --- --- --- --- ------- ------- ------- |
import pathlib
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
import plotly.graph_objs as go
-- -- --- --- --- --- --- --- ------- ------- ------- |
import plotly.offline
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily import logger, format_datetime
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily.operators import resolve_metric, resolve_metric_as_tuple
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily.state import State
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
def metric_parts(metric):
-- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
"""Convert a metric name into the operator and metric names."""
-- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
operator, met = resolve_metric_as_tuple(metric)
-- 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
return operator.name, met.name
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
def graph(config, path, metrics, output=None, x_axis=None, changes=True, text=False):
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
"""
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
Graph information about the cache and runtime.
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:param config: The configuration.
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:type config: :class:`wily.config.WilyConfig`
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:param path: The path to the files.
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:type path: ``list``
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:param metrics: The Y and Z-axis metrics to report on.
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:type metrics: ``tuple``
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:param output: Save report to specified path instead of opening browser.
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
:type output: ``str``
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
"""
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
logger.debug("Running report command")
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
data = []
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
state = State(config)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
abs_path = config.path / pathlib.Path(path)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if x_axis is None:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x_axis = "history"
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
else:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x_operator, x_key = metric_parts(x_axis)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if abs_path.is_dir():
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
paths = [
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
p.relative_to(config.path) for p in pathlib.Path(abs_path).glob("**/*.py")
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
]
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
else:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
paths = [path]
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
operator, key = metric_parts(metrics[0])
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if len(metrics) == 1: # only y-axis
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z_axis = None
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
else:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z_axis = resolve_metric(metrics[1])
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z_operator, z_key = metric_parts(metrics[1])
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
for path in paths:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x = []
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
y = []
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z = []
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
labels = []
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
last_y = None
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
for rev in state.index[state.default_archiver].revisions:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
labels.append(f"{rev.revision.author_name} <br>{rev.revision.message}")
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
try:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
val = rev.get(config, state.default_archiver, operator, str(path), key)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if val != last_y or not changes:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
y.append(val)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if z_axis:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z.append(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
rev.get(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
config,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
state.default_archiver,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z_operator,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
str(path),
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
z_key,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if x_axis == "history":
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x.append(format_datetime(rev.revision.date))
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
else:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x.append(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
rev.get(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
config,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
state.default_archiver,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x_operator,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
str(path),
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x_key,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
last_y = val
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
except KeyError:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
# missing data
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
pass
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
# Create traces
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
trace = go.Scatter(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
x=x,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
y=y,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
mode="lines+markers+text" if text else "lines+markers",
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
name=f"{path}",
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
ids=state.index[state.default_archiver].revision_keys,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
text=labels,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
marker=dict(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
size=0 if z_axis is None else z,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
color=list(range(len(y))),
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
# colorscale='Viridis',
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
),
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
xcalendar="gregorian",
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
hoveron="points+fills",
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
data.append(trace)
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
if output:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
filename = output
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
auto_open = False
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
else:
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
filename = "wily-report.html"
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
auto_open = True
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
y_metric = resolve_metric(metrics[0])
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
title = f"{x_axis.capitalize()} of {y_metric.description} for {path}"
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
plotly.offline.plot(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
{
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
"data": data,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
"layout": go.Layout(
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
title=title,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
xaxis={"title": x_axis},
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
yaxis={"title": y_metric.description},
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
),
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
},
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
auto_open=auto_open,
-- 15 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
filename=filename,
-- -- 006 013 008 015 019 023 0097.70 0338.20 0003.46 |
)