![«косвенные» переменные в foreach](https://rvso.com/image/298795/%C2%AB%D0%BA%D0%BE%D1%81%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5%C2%BB%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5%20%D0%B2%20foreach.png)
Я пытаюсь нарисовать три "графика", которые представляют собой прямоугольники, расположенные рядом. На каждом из них нужно разместить четыре точки. Эти четыре точки и есть "очки".
Использование foreach
цикла для графиков является естественным, поскольку вся компоновка и метки одинаковы.
Чего я не могу понять, так это как передать список данных в каждую итерацию. В других языках я бы использовал что-то вроде вложенного foreach
, используя косвенную переменную, имя которой указывает на данные для построения графика, чтобы разместить точки данных. Я не могу найти косвенную переменную в tikz.
В настоящее время, похоже, что второй \foreach видит только одно значение, а не список из четырех элементов. Я могу использовать неправильный метод. Так что другие стратегии приветствуются.
МВЭ:
\documentclass[]{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
\begin{document}
% Use A4 page shape.
% Base size of one graph is A4 page, but with pt instead of mm.
\begin{tikzpicture}
\pgfmathsetmacro{\scale}{1.75}
\pgfmathsetmacro{\graphHeight}{297 pt/\scale}
\pgfmathsetmacro{\graphWidth}{201 pt/\scale}
\def\labelsM{85, 10, 55, 75}
\def\labelsC{75, 20, 55, 65}
\def\labelsP{65, 30, 55, 55}
\def\graphInfo{ Graph one/{(-\graphWidth pt, 0pt)}/\labelsM,
Graph two/{(0pt, 0pt)}/\labelsC,
Graph three/{(\graphWidth pt, 0pt)}/\labelsP
}
\foreach \name/\pos/\values in \graphInfo
{
% Draw box
\node [
at = {\pos},
draw,
rectangle,
line width = 2pt,
minimum width = \graphWidth pt,
minimum height = \graphHeight pt,
fill = black!15,
name=\name
]
{} ;
% Name graph
\node [
font = \bfseries,
below = 2pt of \name.south
]
{\name} ;
% Vertical lines and labels (should be 4 equidistant vertical lines)
\foreach \s [count=\i] in \values {
\coordinate (top) at ($(\name.north west)!\i/5!(\name.north east)$) ;
\coordinate (bottom) at ($(\name.south west)!\i/5!(\name.south east)$) ;
\draw [dashed] (top) -- (bottom) ;
% Data to be plotted when this works
};
} % end foreach \name
\end{tikzpicture}
решение1
foreach не расширяется \values
полностью, а только на один уровень вглубь. Поэтому он видит только \labelsM
, а не значения. Расширьте его \values
хотя бы один раз перед использованием:
\expandafter\let\expandafter\values\values
\expandafter
расширяет предыдущую команду. Так что первая \expandafter
расширяет вторую \expandafter
, которая расширяет вторую \values
, а \labelsX
затем TeX продолжает выполнять \let
команду. В конце вы получаете \let\values\labelsX
.)