我得到了字母(例如城市)与数字(例如设施)的对应关系,并且数字与权重(例如设施的价格)相关联。我想用类似这样的方式来定义这种对应关系
\myfunction{<facility>}{<price-of-facility>}{<cities-in-which-the-facility-is>}
我想生成一个表格,其中城市为行,设施为列,价格为两者的交集(如果有的话)。当然,这个表格会很稀疏,手工做起来会很麻烦。
有没有办法自动生成这样的表格?
数据示例
- 设施 A(价格**):城市 1、3、5
- B(*):1、4
- C(**):3、4、5
- D(***):2、3
- 乙 (*): 1, 2, 5
或者,使用我上面建议的功能(并用星号写出价格):
- \myfunction{A}{**}{1,3,5}
- \myfunction{B}{*}{1,4}
- \myfunction{C}{**}{3,4,5}
- \myfunction{D}{***}{2,3}
- \myfunction{E}{*}{1,2,5}
答案1
我认为这是可以满足您要求的东西。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{plotmarks}
\usepgfmodule{parser}
\newcounter{stars}
\newif\ifdrawstars
\pgfparserdef{starparser}{initial}{the letter o}%
{\ifdrawstars
\path (\starshift*1pt+\number\value{stars}*6pt,0pt) node{\pgfuseplotmark{o}};
\fi
\stepcounter{stars}}%
\pgfparserdef{starparser}{initial}{the character *}%
{\ifdrawstars
\path (\starshift*1pt+\number\value{stars}*6pt,0pt) node{\pgfuseplotmark{star}};
\fi
\stepcounter{stars}}%
\pgfparserdef{starparser}{initial}{the character ;}%
{\pgfparserswitch{final}}
\pgfmathtruncatemacro\ovalshift{0}
\tikzset{pics/stars/.style={code={
\setcounter{stars}{0}
\drawstarsfalse
\pgfparserparse{starparser}#1;
\pgfmathtruncatemacro\starshift{3-3*\number\value{stars}}
\setcounter{stars}{0}
\drawstarstrue
\pgfparserparse{starparser}#1;
}},pics/stars/.default=*}
\newcommand\myfunction[3]{\path foreach \X in {#1} {
foreach \Y in {#3} {(\X|-\Y) pic{stars=#2}}};}
\begin{document}
\begin{center}
\begin{tikzpicture}[xscale=1,yscale=0.8]
\path foreach \X [count=\Y] in {A,...,F}
{(\Y,0) node (\X){\X}}
foreach \X in {1,...,5} {(0,-\X) node (\X){\X}};
\myfunction{B}{*}{1,4}
\myfunction{C}{**}{3,4,5}
\myfunction{D}{***}{2,3}
\myfunction{E}{*}{1,2,5}
\end{tikzpicture}
\end{center}
\end{document}
在这个第一个版本中,我保留了基本内容。您可以使其更加花哨,并且可以扫描输入以设置“轴”等等。如果有需要更改的内容,请告诉我。
这是一个带有数字的更加可定制的版本。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{plotmarks}
\usepgfmodule{parser}
\newcounter{stars}
\makeatletter
\pgfmathdeclarefunction{Dim}{1}{%
\begingroup%
\pgfutil@tempcnta0%
\@for\pgfutil@tempa:=#1\do{\advance\pgfutil@tempcnta1}%
\edef\pgfmathresult{\the\pgfutil@tempcnta}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}
\makeatletter
\newif\ifdrawstars
\pgfparserdef{starparser}{initial}{the letter o}%
{\stepcounter{stars}}%
\pgfparserdef{starparser}{initial}{the character *}%
{\stepcounter{stars}}%
\pgfparserdef{starparser}{initial}{the character ;}%
{\pgfparserswitch{final}}
\pgfmathtruncatemacro\ovalshift{0}
\tikzset{pics/stars/.style={code={
\setcounter{stars}{0}%
\pgfparserparse{starparser}#1;%
\node{\number\value{stars}};%
}},pics/stars/.default=*,
pics/adjacency table/.style={code={
\tikzset{adjacency table/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/adjacency table/##1}}%
\begin{scope}[local bounding box=tab]
\draw [thick] (-0.5,0.5) rectangle
({2*Dim("\pv{list X}")-0.5},{-2*Dim("\pv{list Y}")-0.5});
\edef\temp{\pv{list X}}
\path foreach \X [count=\Y] in \temp
{(\Y,0) node (X-\X) {\X}};
\edef\temp{\pv{list Y}}
\path foreach \X [count=\Y] in \temp
{(0,-\Y) node (Y-\X) {\X}
\ifnum\Y=0
(0,-\Y+0.5-|tab.west) edge[thick] (0,-\Y+0.5-|tab.east)
\else
(0,-\Y+0.5-|tab.west) edge (0,-\Y+0.5-|tab.east)
\fi};
\edef\temp{\pv{list Y}}
\path foreach \X [count=\Y] in \temp
{\ifnum\Y=1
(\Y-0.5,0|-tab.north) edge[thick] (\Y-0.5,0|-tab.south)
\else
(\Y-0.5,0|-tab.north) edge (\Y-0.5,0|-tab.south)
\fi};
\end{scope}
}},
adjacency table/.cd,list X/.initial={1,...,5},list Y/.initial={A,...,F}}
\newcommand\myfunction[3]{\path foreach \X in {#1} {
foreach \Y in {#3} {(Y-\X-|X-\Y) pic{stars=#2}}};}
\begin{document}
\begin{center}
\begin{tikzpicture}
\pic[xscale=0.9,yscale=0.7]{adjacency table={list X={1,...,5},list Y={A,...,F}}};
\myfunction{B}{*}{1,4}
\myfunction{C}{**}{3,4,5}
\myfunction{D}{***}{2,3}
\myfunction{E}{*}{1,2,5}
\end{tikzpicture}
\end{center}
\end{document}