112 lines
4 KiB
Python
112 lines
4 KiB
Python
import numpy as np
|
||
import matplotlib.pyplot as plt
|
||
from matplotlib.patheffects import Stroke, Normal
|
||
|
||
forges = {
|
||
"Trac" : [ (2004, 2024, "C0") ],
|
||
"Redmine" : [ (2006, 2024, "C0") ],
|
||
"SourceForge": [ (2000,2002,"C2"),
|
||
(2002,2002,"C2"),
|
||
(2002,2012,"C1")],
|
||
"GForge": [ (2002, 2009, "C5"),
|
||
(2009, 2009, "C5"),
|
||
(2009, 2024, "C1") ],
|
||
"FusionForge" : [ (2009, 2018, "C5"),
|
||
(2018, 2024, ".75") ],
|
||
"Allura": [ (2009,2024,"C7") ],
|
||
"GitLab" : [ (2011, 2013, "C4"),
|
||
(2013, 2024, "C3")],
|
||
"Tuleap" : [ (2011, 2024, "C0") ],
|
||
"Gogs": [ (2014, 2024, "C0"),
|
||
(2016, 2016, "C0"),
|
||
(2016, 2024, "C0")],
|
||
"Gitea": [ (2016, 2022, "C0"),
|
||
(2022, 2022, "C0"),
|
||
(2022, 2024, "C1") ],
|
||
"Forgejo": [ (2022, 2024, "C0") ],
|
||
"SourceHut": [ (2018, 2024, "C6") ],
|
||
"Gitorious" : [ (2009, 2015, "C0") ],
|
||
"sourceforge.net" : [ (1999, 2012, "C2"),
|
||
(2012, 2024, "C7") ],
|
||
"forge.objectweb.org" : [ (2002, 2003, "C2"),
|
||
(2003, 2007, "C5"),
|
||
(2007, 2007, "C5") ],
|
||
"forge.ow2.org" : [ (2007, 2018, "C5"),
|
||
(2018, 2018, "C5") ],
|
||
"gitlab.ow2.org" : [ (2017, 2024, "C3") ],
|
||
"gforge.inria.fr": [ (2005, 2021, "C5"),
|
||
(2021,2021, "C5") ],
|
||
"gitlab.inria.fr": [ (2016, 2024, "C3") ],
|
||
"forge.imag.fr": [ (2009, 2016, "C5"),
|
||
(2016,2016, "C5") ],
|
||
"gricad‐gitlab.univ‐grenoble‐alpes.fr": [ (2016, 2024, "C3") ],
|
||
"gitlab.huma-num.fr": [ (2016, 2024, "C3") ],
|
||
"sourcesup.renater.fr" : [ (2004, 2024, "C5") ],
|
||
"code.google.com" : [ (2007, 2014, "C1") ],
|
||
"bitbucket.org" : [ (2008, 2024, "C1") ],
|
||
"github.com" : [ (2008, 2024, "C1") ],
|
||
"gitlab.com" : [ (2012, 2014, "C4"),
|
||
(2014, 2024, "C3") ],
|
||
"sr.ht": [ (2018, 2024, "C6") ]
|
||
}
|
||
|
||
|
||
figure = plt.figure(figsize=(10,7))
|
||
ax = plt.subplot(1,1,1)
|
||
|
||
for i, (name, segments) in enumerate(forges.items()):
|
||
text = ax.text(segments[0][0], i, name+" ",
|
||
horizontalalignment="right",
|
||
verticalalignment="center")
|
||
text.set_path_effects([Stroke(linewidth=2.5, foreground="white"), Normal()])
|
||
|
||
for (start, stop, color) in segments:
|
||
X = [start, stop]
|
||
Y = [i,i+1] if start == stop else [i,i]
|
||
ax.plot(X, Y, marker="o", color=color, linewidth=2)
|
||
ax.plot(X, Y, linestyle="", marker="o", color="white", markersize=3)
|
||
|
||
|
||
xticks = np.arange(1998, 2024, 2)
|
||
labels = [f"{year}" if year != 2004 else "2004\ngit " for year in xticks]
|
||
ax.set_xticks(xticks)
|
||
ax.set_xticklabels(labels)
|
||
ax.set_xlim(1998,2023.1)
|
||
ax.set_yticks([])
|
||
|
||
# Line for git creation in 2004
|
||
ax.axvline(2004, color="black", zorder=-1, linestyle=":")
|
||
|
||
ax.spines["right"].set_visible(False)
|
||
ax.spines["left"].set_visible(False)
|
||
ax.spines["top"].set_visible(False)
|
||
# ax.spines["bottom"].set_visible(False)
|
||
ax.grid(lw=.25, ls="-", color="black", alpha=.25)
|
||
|
||
# Legend
|
||
from matplotlib.lines import Line2D
|
||
lines = [Line2D([0], [0], color="C0", lw=4),
|
||
Line2D([0], [0], color="C1", lw=4),
|
||
Line2D([0], [0], color="C2", lw=4),
|
||
Line2D([0], [0], color="C3", lw=4),
|
||
Line2D([0], [0], color="C4", lw=4),
|
||
Line2D([0], [0], color="C5", lw=4),
|
||
Line2D([0], [0], color="C6", lw=4),
|
||
Line2D([0], [0], color=".75", lw=4)]
|
||
ax.legend(
|
||
lines, ['Logiciels libres',
|
||
'Logiciels non libres',
|
||
'Forge originale',
|
||
'GitLab (projets publics)',
|
||
'GitLab (projets privés)',
|
||
'GForge/FusionForge',
|
||
'SourceHut',
|
||
'Plus de nouvelle version'],
|
||
edgecolor="None",
|
||
ncol=len(lines)//2,
|
||
loc="upper left",
|
||
bbox_to_anchor=(0, 1.1),
|
||
borderaxespad=0)
|
||
|
||
plt.savefig("forge-timelines.png")
|
||
# plt.show()
|