我想重现像这样的层次语义网络(记忆和学习,从大脑到行为”,Mark A. Gluck)
我的主要问题是在每个框中添加侧面信息。也许,最好的方法是编写一个函数,其中的参数应该是框侧面和属性列表。
我的代码:
\startMPdefinitions
input boxes;
\stopMPdefinitions
\starttext
\startMPcode
%% boxes names
boxit.animal ("Animal");
boxit.fish ("Fish");
boxit.bird ("Bird");
boxit.mammal ("Mammal");
boxit.canary("Canary");
boxit.ostrich("Ostrich");
boxit.dog("Dog");
boxit.dolphin("dolphin");
boxit.chi("Chihuahua");
boxit.dal("Dalmation");
boxit.fido("Fido");
%% boxes positions
fish.c = origin;
fish.c = animal.c - 60 up;
animal.c = .5[bird.c,mammal.c] + 60 up;
bird.c - fish.c= fish.c - mammal.c = 90 left;
ostrich.c = bird.c + 60 down;
canary.c = ostrich.c + 50 left;
dolphin.c = mammal.c + 20 right + 60 down;
dog.c = dolphin.c + 50 left;
chi.c = dog.c + 50 left + 60 down;
dal.c = dog.c + 50 right + 60 down;
fido.c = dal.c + 60 down;
forsuffixes x = animal, fish, mammal, bird, ostrich, canary, dog, dolphin, chi, dal, fido:
drawboxed(x);
endfor
%%% arrows and paths
path p[];
p1 = animal.sw -- bird.ne;
p2 = animal.s--fish.n;
p3 = animal.se -- mammal.nw;
p4 = bird.s--ostrich.n;
p5 = bird.s--canary.ne;
p6=mammal.s--dog.n;
p7=dog.s--chi.n;
p8=dog.s--dal.n;
p9=dal.s--fido.n;
p10=mammal.s--dolphin.n;
for i=1 upto 10:
drawarrow p[i];
endfor
\stopMPcode
\stoptext
我的输出:
谢谢大家
答案1
我发布这篇文章是因为您表示有兴趣查看 TikZ/Forest 版本。Forest 是基于 TikZ 绘制树木的最灵活、最强大的方法。但是,我不确定这是否与 ConTeXt 兼容,尽管 TikZ 本身兼容。显然您不需要inputenc
,例如,我在这里使用它来处理 unicode 引号。如果愿意,可以用 TeX 标记替换它们。我只是习惯以这种方式输入它们。但 Forest 本身似乎是一个 LaTeX 包……
树使用forest
并且树的自定义格式使用backgrounds
TikZ 库。此处的引号由 处理csquotes
,但这显然是可选的。
\begin{forest}
如果要将树的前言用于多棵树,则应将其移至 Forest 样式。这里,我们只需定制一棵特定的树。
for tree={
引用的属性不是节点,而是后来添加的。所以我们需要让树比原来更宽敞一些。
fit=band,
s sep+=20pt,
这确保了当父级有奇数个子级(例如 3)时,它与中间的子级(例如第二个)对齐。
if={isodd(n_children)}{%
calign primary child={int((n_children()+1)/2)},
calign=child,
}{},
这是我们的自定义边配置。缩短实际上是延长线条以补偿 的使用rounded corners
。为了避免在不通过角落绘制时将边绘制在节点上方,我们将边绘制on background layer
在节点后面。
edge={ultra thick, orange!50!yellow, shorten <=-5pt, shorten >=-5pt},
edge path={%
\noexpand\scoped[on background layer]
\noexpand\path [\forestoption{edge}] (!u) -- ()\forestoption{edge label};
},
自定义节点配置具有圆角、粗彩色边框和浅色填充。
draw=orange!50!yellow,
rounded corners=5pt,
ultra thick,
inner color=orange!75!yellow!10,
outer color=orange!75!yellow!25,
我们对节点文本使用 sans 字体,并采用固定高度/深度,以便我们的节点看起来对齐得很好。
font=\sffamily,
text height=2ex,
text depth=.5ex,
},
这只是 TikZ 风格,my pins
对于引用的位,它与主节点的配置类似。
/tikz/my pins/.style={font=\sffamily\footnotesize, text height=1ex, text depth=.25ex, inner sep=1pt},
Aright pin
是添加到主节点之一右侧的自定义 TikZ 节点。它接受 2 个以冒号分隔的参数:<angle>:<text>
。
right pin/.style args={#1:#2}{%
tikz+={%
\scoped[on background layer]\draw [thick, draw=orange!50!yellow, shorten <=-5pt] () -- ++(#1:35pt) node [right, my pins] {‘#2’};
}
},
right pins
<angle>:<text>
采用要传递给的参数列表right pin
。
right pins/.style={%
split={#1}{,}{right pin}
},
left pin
和与和left pins
类似,但不出所料,它们指的是主节点左侧而不是右侧的引用文本。right pin
right pins
left pin/.style args={#1:#2}{%
tikz+={%
\scoped[on background layer]\draw [thick, draw=orange!50!yellow, shorten <=-5pt] () -- ++(#1:35pt) node [my pins, left] {‘#2’};
}
},
left pins/.style={%
split={#1}{,}{left pin}
},
树的前言就完成了。现在来说明树的规范,从根节点开始,该节点有 3 个属性在右侧引用。因此我们使用“right pins={:,:,:}”。
[Animal, right pins={40:can move,20:eats,0:reproduces}
left pins
我们继续使用同样的方式在左边引用一个具有 3 个属性的节点。
[Bird, left pins={-160:lays eggs,180:is warm-blooded,160:has feathers}
接下来的2个节点分别有2left pins
和2 right pins
。
[Canary, left pins={-170:is small,170:works in coal mines}
]
[Ostrich, right pins={-10:cannot fly,10:is quite large}
]
]
我们继续,以同样的方式完成并注释树。
[Fish, right pins={-10:has gills,10:can swim}
]
[Mammal, right pins={-15:has fur,5:produces milk,25:bears live young,45:breathes air}
[Dog, left pins={170:barks,-170:wags tail}
[Chihuahua, left pins={-170:is teeny,170:is fierce}
]
[Dalmation, right pins={-10:has 100 siblings,10:is spotted}
[Fido, right pins={-10:has red kennel,10:is scared of mice}
]
]
]
[Dolphin, right pins={-10:is highly social,10:lives in pods}
]
]
]
关闭环境
\end{forest}
我们就完成了。
完整代码:
\documentclass[border=10pt,tikz,multi]{standalone}
\usepackage{forest}
\usepackage[utf8]{inputenc}
\usepackage{csquotes}
\MakeAutoQuote{‘}{’}
\MakeAutoQuote*{“}{”}
\usetikzlibrary{backgrounds}
\begin{document}
\begin{forest}
for tree={
fit=band,
s sep+=20pt,
if={isodd(n_children)}{%
calign primary child={int((n_children()+1)/2)},
calign=child,
}{},
edge={ultra thick, orange!50!yellow, shorten <=-5pt, shorten >=-5pt},
edge path={%
\noexpand\scoped[on background layer]
\noexpand\path [\forestoption{edge}] (!u) -- ()\forestoption{edge label};
},
draw=orange!50!yellow,
rounded corners=5pt,
ultra thick,
inner color=orange!75!yellow!10,
outer color=orange!75!yellow!25,
font=\sffamily,
text height=2ex,
text depth=.5ex,
},
/tikz/my pins/.style={font=\sffamily\footnotesize, text height=1ex, text depth=.25ex, inner sep=1pt},
right pin/.style args={#1:#2}{%
tikz+={%
\scoped[on background layer]\draw [thick, draw=orange!50!yellow, shorten <=-5pt] () -- ++(#1:35pt) node [right, my pins] {‘#2’};
}
},
right pins/.style={%
split={#1}{,}{right pin}
},
left pin/.style args={#1:#2}{%
tikz+={%
\scoped[on background layer]\draw [thick, draw=orange!50!yellow, shorten <=-5pt] () -- ++(#1:35pt) node [my pins, left] {‘#2’};
}
},
left pins/.style={%
split={#1}{,}{left pin}
},
[Animal, right pins={40:can move,20:eats,0:reproduces}
[Bird, left pins={-160:lays eggs,180:is warm-blooded,160:has feathers}
[Canary, left pins={-170:is small,170:works in coal mines}
]
[Ostrich, right pins={-10:cannot fly,10:is quite large}
]
]
[Fish, right pins={-10:has gills,10:can swim}
]
[Mammal, right pins={-15:has fur,5:produces milk,25:bears live young,45:breathes air}
[Dog, left pins={170:barks,-170:wags tail}
[Chihuahua, left pins={-170:is teeny,170:is fierce}
]
[Dalmation, right pins={-10:has 100 siblings,10:is spotted}
[Fido, right pins={-10:has red kennel,10:is scared of mice}
]
]
]
[Dolphin, right pins={-10:is highly social,10:lives in pods}
]
]
]
\end{forest}
\end{document}
答案2
根据 cfr 的建议,我发布了自己的代码,因为 Tikz/forest 在 ConteXt 中不起作用。函数 pins(box name)(left "e" or right "d")("characteristic one","characteristic two", ...) 可以完成这项工作。
\startMPdefinitions
input boxes;
\stopMPdefinitions
\starttext
\startMPcode
% best guess at the required colors
color mid_blue, dark_blue, laranja, dentro, fora;
mid_blue = (79/255, 129/255, 189/255);
dark_blue = (56/255, 93/255, 138/255);
laranja=(1,0.6,0);
dentro = .75*laranja + .10*yellow;
fora = .75*laranja + .25*yellow;
%% boxes names
boxit.animal ("Animal");
boxit.fish ("Peixe");
boxit.bird ("Ave");
boxit.mammal ("Mamífero");
boxit.canary("Canário");
boxit.ostrich("Avestruz");
boxit.dog("Cão");
boxit.dolphin("Golfinho");
boxit.chi("Chihuahua");
boxit.dal("Dálmata");
boxit.fido("Aika");
%% boxes positions
fish.c = origin;
fish.c = animal.c - 40 up;
animal.c = .5[bird.c,mammal.c] + 40 up;
bird.c - fish.c= fish.c - mammal.c = 130 left;
ostrich.c = bird.c + 40 down;
canary.c = ostrich.c + 70 left;
dolphin.c = mammal.c + 30 right + 40 down;
dog.c = dolphin.c + 75 left;
chi.c = dog.c + 60 left + 40 down;
dal.c = dog.c + 60 right + 40 down;
fido.c = dal.c + 40 down;
forsuffixes x = animal, fish, mammal, bird, ostrich, canary, dog, dolphin, chi, dal, fido:
x.ne-x.sw = (60,20);
fill bpath x withcolor fora;
draw pic x withcolor \MPcolor{darkred};
draw bpath x withcolor dentro;
endfor
%%% arrows and paths
path p[];
p1 = animal.sw -- bird.ne;
p2 = animal.s--fish.n;
p3 = animal.se -- mammal.nw;
p4 = bird.s--ostrich.n;
p5 = bird.s--canary.ne;
p6=mammal.s--dog.n;
p7=dog.s--chi.n;
p8=dog.s--dal.n;
p9=dal.s--fido.n;
p10=mammal.s--dolphin.n;
%%%%
def pins(suffix caixa)(expr local)(text thelabels) =
pair pos[];
string name[], sitio;
if local="d":
pos1=caixa.e;
pos2=caixa.se; pos3=caixa.ne;
else:
pos1=caixa.w;
pos3=caixa.sw; pos2=caixa.nw;
fi;
path cami, lixo;
cami := pos3 -- pos2;
k:= 0; for t = thelabels: k := k+1; name[k] = t; endfor
for i = 1 upto k:
pos4 := (i/(k+1))[pos2,pos3];
pos5 := pos4 if local="d": + else: - fi (20, i*2);
label.if local="d": rt else: lft fi(textext(name[i]) scaled .5, pos5);
draw pos4 -- pos5;
endfor;
enddef;
drawoptions(withpen pencircle scaled 1 pt withcolor mid_blue);
for i=1 upto 10:
draw p[i];
endfor
pins(animal)("d")("Come","Move-se", "Reproduz-se");
pins(bird)("e")("tem asas","pode voar", "põe ovos");
pins(mammal)("d")("respira ar","produzem leite","têm pele");
pins(dolphin)("d")("vivem na água","têm barbatanas");
pins(dal)("d")("têm pontos negros","máscote dos bombeiros");
pins(fido)("d")("animal de estimação","gosta de doces");
pins(chi)("e")("é castanho","é pequeno");
pins(dog)("e")("tem pelo","têm cauda");
pins(canary)("e")("é amarelo","canta");
pins(ostrich)("d")("não voa","é grande");
pins(fish)("e")("vive na água","têm cauda");
\stopMPcode
\stoptext
输出: