Last active
November 30, 2022 06:54
-
-
Save owulveryck/3c48bd15d1bbc146e5d70ff8e5f5c39e to your computer and use it in GitHub Desktop.
Article Wardley sources
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Stages of evolution | |
package main | |
import ( | |
"image/color" | |
"log" | |
"math" | |
"os" | |
"golang.org/x/image/font/opentype" | |
"gonum.org/v1/plot" | |
"gonum.org/v1/plot/font" | |
"gonum.org/v1/plot/plotter" | |
) | |
func main() { | |
ttf, err := os.ReadFile("CenturyGothic.ttf") | |
if err != nil { | |
panic(err) | |
} | |
fontTTF, err := opentype.Parse(ttf) | |
if err != nil { | |
log.Fatal(err) | |
} | |
centuryGothic := font.Font{Typeface: "Century Gothic"} | |
font.DefaultCache.Add([]font.Face{ | |
{ | |
Font: centuryGothic, | |
Face: fontTTF, | |
}, | |
}) | |
plot.DefaultFont = centuryGothic | |
sigmoid := func(x float64) float64 { | |
return (1.0 / (1.0 + 0.2*math.Exp(-x))) | |
} | |
line := plotter.NewFunction(sigmoid) | |
line.Width = 4 | |
line.Samples = 5000 | |
line.Color = color.RGBA{R: 47, G: 175, B: 200, A: 255} | |
p := plot.New() | |
// p.Add(line2) | |
p.Y.Max = 1.1 | |
p.Y.Min = 0 | |
p.X.Max = 5 | |
p.X.Min = -5 | |
steps := []stage{ | |
{name: "", evolution: 0}, | |
{name: "Genesis", evolution: 20, color: color.RGBA{R: 43, G: 162, B: 188, A: 255}}, | |
{name: "Custom Built", evolution: 40, color: color.RGBA{R: 100, G: 194, B: 211, A: 255}}, | |
{name: "Product + Rental", evolution: 70, color: color.RGBA{R: 135, G: 208, B: 221, A: 255}}, | |
{name: "Commodity", evolution: 100, color: color.RGBA{R: 219, G: 241, B: 245, A: 255}}, | |
} | |
for i, s := range steps { | |
if i == 0 { | |
continue | |
} | |
var x0, x1, y0, y1 float64 | |
x0 = (p.X.Max-p.X.Min)*steps[i-1].evolution/100 + p.X.Min - (p.X.Max-p.X.Min)*0.03 | |
x1 = (p.X.Max-p.X.Min)*steps[i].evolution/100 + p.X.Min + (p.X.Max-p.X.Min)*0.03 | |
y0 = sigmoid(x0) - 0.03*(p.Y.Max+p.Y.Min) | |
y1 = sigmoid(x1) + 0.03*(p.Y.Max+p.Y.Min) | |
stage, err := plotter.NewLine(plotter.XYs{ | |
{X: x0, Y: y0}, {X: x0, Y: y1}, {X: x1, Y: y1}, {X: x1, Y: y0}, {X: x0, Y: y0}, | |
}) | |
if err != nil { | |
log.Panic(err) | |
} | |
stage.FillColor = s.color | |
stage.Color = s.color | |
p.Add(stage) | |
p.Legend.Add(s.name, stage) | |
} | |
for _, s := range steps { | |
x := (p.X.Max-p.X.Min)*s.evolution/100 + p.X.Min | |
stage, err := plotter.NewLine(plotter.XYs{ | |
{X: x, Y: p.Y.Min}, | |
{X: x, Y: p.Y.Max}, | |
}) | |
if err != nil { | |
log.Panic(err) | |
} | |
if s.evolution != 100 { | |
p.Add(stage) | |
} | |
} | |
p.X.Label.Text = "Certitude" | |
p.X.Label.TextStyle.Color = color.RGBA{R: 33, G: 44, B: 93, A: 255} | |
p.X.Tick.Marker = &ticker{} | |
p.Y.Tick.Marker = &ticker{} | |
p.Y.Label.TextStyle.Color = color.RGBA{R: 33, G: 44, B: 93, A: 255} | |
p.Y.Label.Text = "Présence" | |
p.Title.Text = "Activités" | |
p.Add(line) | |
w, err := p.WriterTo(600, 400, "png") | |
if err != nil { | |
log.Panic(err) | |
} | |
_, err = w.WriteTo(os.Stdout) | |
if err != nil { | |
log.Panic(err) | |
} | |
} | |
type ticker struct{} | |
// Ticks returns Ticks in a specified range | |
func (ticker *ticker) Ticks(min float64, max float64) []plot.Tick { | |
return []plot.Tick{} | |
} | |
type stage struct { | |
name string | |
evolution float64 | |
color color.Color | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
title Salon de thé | |
anchor Business [0.95, 0.63] | |
anchor Public [0.95, 0.78] | |
component Tasse de thé [0.79, 0.61] label [19, -4] | |
component Tasse [0.73, 0.78] | |
component Thé [0.63, 0.81] | |
component Eau Chaude [0.52, 0.80] | |
component Eau [0.38, 0.82] | |
component Bouilloire [0.38, 0.65] label [-66, -33] | |
component Power [0.1, 0.7] label [-27, 20] | |
Business->Tasse de thé | |
Public->Tasse de thé | |
Tasse de thé->Tasse | |
Tasse de thé->Thé | |
Tasse de thé->Eau Chaude | |
Eau Chaude->Eau | |
Eau Chaude->Bouilloire | |
Bouilloire->Power |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<svg width="100%" height="100%" viewBox="0 0 1200 700" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet"> | |
<style><![CDATA[ | |
.evolutionEdge { | |
stroke-dasharray: 7; | |
stroke-dashoffset: 7; | |
animation: dash 3s linear forwards infinite; | |
} | |
@keyframes dash { | |
from { | |
stroke-dashoffset: 100; | |
} | |
to { | |
stroke-dashoffset: 0; | |
} | |
}]]></style> | |
<rect x="0" y="0" width="1200" height="700" fill="rgb(236,237,243)" fill-opacity="0.0"></rect> | |
<defs> | |
<linearGradient id="wardleyGradient" x1="0%" y1="0%" x2="100%" y2="0%"> | |
<stop offset="0%" stop-color="rgb(236,237,243)"></stop> | |
<stop offset="30%" stop-color="rgb(255,255,255)"></stop> | |
<stop offset="70%" stop-color="rgb(255,255,255)"></stop> | |
<stop offset="100%" stop-color="rgb(236,237,243)"></stop> | |
</linearGradient> | |
<marker id="arrow" refX="15" refY="0" markerWidth="12" markerHeight="12" viewBox="0 -5 10 10"> | |
<path d="M0,-5L10,0L0,5" fill="rgb(255,0,0)"></path> | |
</marker> | |
<marker id="graphArrow" refX="9" refY="0" markerWidth="12" markerHeight="12" viewBox="0 -5 10 10"> | |
<path d="M0,-5L10,0L0,5" fill="rgb(0,0,0)"></path> | |
</marker> | |
</defs> | |
<rect x="30" y="50" width="1120" height="600" style="fill:url(#wardleyGradient)"></rect> | |
<g transform=" translate(30,650) rotate(270)"> | |
<line x1="0" y1="0" x2="600" y2="0" stroke-width="1" marker-end="url(#graphArrow)" stroke="rgb(19,36,84)" stroke-opacity="1.0"></line> | |
<line x1="0" y1="194" x2="600" y2="194" stroke-width="1" stroke-dasharray="2 2" stroke="rgb(19,36,84)" stroke-opacity="1.0"></line> | |
<line x1="0" y1="448" x2="600" y2="448" stroke-width="1" stroke-dasharray="2 2" stroke="rgb(19,36,84)" stroke-opacity="1.0"></line> | |
<line x1="0" y1="784" x2="600" y2="784" stroke-width="1" stroke-dasharray="2 2" stroke="rgb(19,36,84)" stroke-opacity="1.0"></line> | |
<text x="5" y="-10" fill="rgb(19,36,84)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" text-anchor="start">Invisible</text> | |
<text x="595" y="-10" fill="rgb(19,36,84)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" text-anchor="end">Visible</text> | |
<text x="300" y="-10" fill="rgb(19,36,84)" fill-opacity="1.0" font-weight="bold" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" text-anchor="middle">Value Chain</text> | |
</g> | |
<line x1="30" y1="650" x2="1150" y2="650" marker-end="url(#graphArrow)" stroke="rgb(19,36,84)" stroke-opacity="1.0"></line> | |
<text x="37" y="65" fill="rgb(19,36,84)" fill-opacity="1.0" font-weight="bold" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" font-size="11px" text-anchor="start">Uncharted</text> | |
<text x="1145" y="65" fill="rgb(19,36,84)" fill-opacity="1.0" font-weight="bold" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" font-size="11px" text-anchor="end">Industrialised</text> | |
<text x="30" y="665" fill="rgb(19,36,84)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Phase I</text> | |
<text x="224" y="665" fill="rgb(19,36,84)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Phase II</text> | |
<text x="478" y="665" fill="rgb(19,36,84)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Phase III</text> | |
<text x="814" y="665" fill="rgb(19,36,84)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Phase IV</text> | |
<text x="1150" y="665" fill="rgb(19,36,84)" fill-opacity="1.0" font-weight="bold" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" text-anchor="end">Evolution</text> | |
<text x="600" y="20" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" text-anchor="middle">Salon de thé</text> | |
<g id="layer_0"> | |
<g id="element_0"> | |
<g transform=" translate(735,80)"> | |
<text x="0" y="0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" font-size="14px" text-anchor="middle">Business</text> | |
</g> | |
</g> | |
<g id="element_1"> | |
<g transform=" translate(903,80)"> | |
<text x="0" y="0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif" font-size="14px" text-anchor="middle">Public</text> | |
</g> | |
</g> | |
</g> | |
<g id="layer_5"> | |
<g id="edge_2_3"> | |
<line x1="713" y1="176" x2="903" y2="212" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_2_5"> | |
<line x1="713" y1="176" x2="926" y2="338" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_5_6"> | |
<line x1="926" y1="338" x2="948" y2="422" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_5_7"> | |
<line x1="926" y1="338" x2="758" y2="422" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_0_2"> | |
<line x1="735" y1="80" x2="713" y2="176" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_7_8"> | |
<line x1="758" y1="422" x2="814" y2="590" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_2_4"> | |
<line x1="713" y1="176" x2="937" y2="272" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
<g id="edge_1_2"> | |
<line x1="903" y1="80" x2="713" y2="176" stroke-width="1" stroke="rgb(128,128,128)" stroke-opacity="1.0"></line> | |
</g> | |
</g> | |
<g id="layer_10"> | |
<g id="element_3"> | |
<g transform=" translate(903,212)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="10" y="10" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Tasse</text> | |
</g> | |
</g> | |
<g id="element_5"> | |
<g transform=" translate(926,338)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="10" y="10" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Eau Chaude</text> | |
</g> | |
</g> | |
<g id="element_8"> | |
<g transform=" translate(814,590)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="-27" y="20" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Power</text> | |
</g> | |
</g> | |
<g id="element_2"> | |
<g transform=" translate(713,176)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="19" y="-4" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Tasse de thé</text> | |
</g> | |
</g> | |
<g id="element_4"> | |
<g transform=" translate(937,272)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="10" y="10" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Thé</text> | |
</g> | |
</g> | |
<g id="element_6"> | |
<g transform=" translate(948,422)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="10" y="10" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Eau</text> | |
</g> | |
</g> | |
<g id="element_7"> | |
<g transform=" translate(758,422)"> | |
<circle cx="0" cy="0" r="5" fill="rgb(255,255,255)" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-opacity="1.0" stroke-width="1"></circle> | |
<text x="-66" y="-33" fill="rgb(0,0,0)" fill-opacity="1.0" font-family="Century Gothic,CenturyGothic,AppleGothic,sans-serif">Bouilloire</text> | |
</g> | |
</g> | |
</g> | |
</svg> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
title Salon de thé | |
anchor Business [0.95, 0.06] | |
anchor Public [0.95, 0.14] | |
component Tasse de thé [0.78, 0.09] label [19, -4] | |
component Tasse [0.73, 0.12] label [6, 30] | |
component Thé [0.58, 0.05] | |
component Eau Chaude [0.44, 0.10] | |
component Eau [0.38, 0.14] label [-22, 23] | |
component Bouilloire [0.30, 0.10] label [-66, -33] | |
component Power [0.12, 0.10] label [-27, 20] | |
Business->Tasse de thé | |
Public->Tasse de thé | |
Tasse de thé->Tasse | |
Tasse de thé->Thé | |
Tasse de thé->Eau Chaude | |
Eau Chaude->Eau | |
Eau Chaude->Bouilloire | |
Bouilloire->Power |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment