custom colour wheel
Different background color and gradient fill are from this answer.
Center imaging is from my recently answer, using pullquote
environment.
And the whole code is as follow:
\documentclass[border=20pt]{standalone}
\usepackage{xcolor}
\usepackage{tikz,pgf,xparse}
\usepackage{pgfmath}
\usepackage{xifthen}
\usetikzlibrary{decorations.text, arrows.meta,calc,shadows.blur,shadings}
\renewcommand*\familydefault{\sfdefault} % Set font to serif family
%%%%%%%%%%%%%%%%% FOR COLOR TRANSITION %%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\vardonut}[1]{
\newcounter{num}
\foreach \content/\size/\colour in {#1}
\stepcounter{num};
\foreach \content/\size/\colour [count=\i] in {#1}{
\draw[white,very thick,top color=\colour!50!black, bottom color=\colour, shading angle={-90+360/\thenum/2+(\i-1)*360/\thenum}]
({2*cos((\i-1)*360/\thenum)},{2*sin((\i-1)*360/\thenum)}) arc[radius = 2, start angle={(\i-1)*360/\thenum}, delta angle=360/\thenum] --
({(2+\size)*cos(\i*360/\thenum)},{(2+\size)*sin(\i*360/\thenum)}) arc[radius = {2+\size}, start angle={\i*360/\thenum}, delta angle=-360/\thenum] --
cycle;
% \node[white,font=\large] at ({(\i-1)*360/\thenum+360/\thenum/2}:{\size/2+2}) {\content};
}
}
%%%%%%%%%%%%%%%%%%%%%END OF COLOR TRANSITION %%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[
% Environment Cfg
font=\Large,
scale=1,
% Styles
Grid/.style={
loosely dotted,
line width=1.5pt,
color=black
},
Separator/.style={
thick,
color=black!50
},
Border/.style={
line width=1pt,
color=red!60
},
Border2/.style={
line width=2pt,
color=red!60
},
Fill/.style={
fill=black,
opacity=0.1
}
]
% lifeweel from many codes arround TEX.SE
%Variables: 1:levels, 2:grid 3:number of features 4: Feature_name/quantity
% 5: anchor aling 6: numbers position 7:Relative position 8:ID
\def\lifeweel#1#2#3#4[#5][#6](#7)(#8){%
\begin{scope}[shift={(#7)}]
%Decoration
\foreach \n in {0,#2,...,#1}{
\draw[fill=black, opacity=0.1] (0,0) circle [radius=\n];}
%Drawing the grid and numbers.
\foreach \n in {0,#2,...,#1}{
\draw[Grid] (0,0) circle [radius=\n];
\node[anchor=#5] (A) at (#6:\n+0.2){\n};}
%Drawing features separations.
\foreach \m [count=\i] in {0,1,...,#3}{
\draw[Separator] (0,0) -- (360/#3*\i: #1);}
%Drawing the border
\draw[Border] (0,0) circle [radius=#1];
%Drawing the names
\foreach \o/\p [count=\j] in {#4}{
\pgfmathparse{int(360/#3*\j)}
\ifthenelse{ \pgfmathresult >180}
{% True
\path[%Reverse
decoration={
raise = -0.8ex,
text along path,
text = {|\huge|\o},
text align = center,
reverse path
},
decorate
]
(360/#3*\j:#1+0.7) arc (360/#3*\j:360/#3*(\j-1):#1+0.7);%\path
}
{%False
\path[%Normal
decoration={
raise = -0.8ex,
text along path,
text = {|\huge|\o},
text align = center
},
decorate
]
(360/#3*\j:#1+0.7) arc (360/#3*\j:360/#3*(\j-1):#1+0.7); %Path
}
\draw[Border2]
(360/#3*\j:\p) coordinate (#8a\j)
arc (360/#3*\j:360/#3*(\j-1):\p) coordinate (#8b\j);
\draw[fill=red, opacity=0.2]
(0,0) -- (360/#3*\j:\p) arc (360/#3*\j:360/#3*(\j-1):\p);
}
\pgfmathparse{int(#3+1)} % Principle of uroboro
\coordinate (#8b\pgfmathresult) at (#8b1);
\foreach \o/\p [count=\i, evaluate=\i as \x using int(\i+1)] in {#4}{%Close the perimete
\draw[Border2] (#8a\i) -- (#8b\x);}
\end{scope}
}
%Variables: 1:levels, 2:grid 3:number of features 4: Feature_name/quantity
% 5: anchor aling 6: numbers position 7:Relative position 8: ID
\def\lifeweelS#1#2#3#4[#5][#6](#7)(#8){%
\begin{scope}[shift={(#7)}]
%Drawing the numbers.
\foreach \n [count=\m] in {0,#2,...,#1}{
\node[anchor=#5] (A) at (#6:\n+0.2){\n};
}
%Drawing the grid
\foreach \n in {0,#2,...,#1}{
\foreach [count=\i, evaluate=\i as \x using int(\i+1)]\m in {0,1,...,#3}{
\draw[Grid](360/#3*\i:\n) -- (360/#3*\x:\n);
\draw[Fill](360/#3*\i:\n) -- (0,0) -- (360/#3*\x:\n);
}
}
%Drawing features separations.
\foreach \m [count=\i] in {0,1,...,#3}{
\draw[Separator] (0,0) -- (360/#3*\i: #1);}
%Drawing the border
\draw[fill=black, opacity=0.1] (0,0) circle [radius=#1];
\draw[Border] (0,0) circle [radius=#1];
%Drawing the names
\foreach \o/\p [count=\j from 0] in {#4}{
\pgfmathparse{int(360/#3*\j)}
\ifthenelse{\pgfmathresult =90 \OR \pgfmathresult =270}
{%True
\draw (360/#3*\j:#1+0.7) node [anchor=center]{\huge\o};
}
{%false
\ifthenelse{\pgfmathresult <90 \OR \pgfmathresult >270}
{% True
\draw (360/#3*\j:#1+0.7) node [anchor=west]{\huge\o};
}
{%False
\draw (360/#3*\j:#1+0.7) node [anchor=east]{\huge\o};
}
}
\coordinate (#8c\j) at (360/#3*\j:\p);
}
\coordinate (#8c#3) at (#8c0);
\foreach \o/\p [count=\i from 0, evaluate=\i as \x using int(\i+1)] in {#4}{%Close the perimete
\draw[Border2] (#8c\i) -- (#8c\x);
\draw[fill=red, opacity=.2] (#8c\i) --(0,0) -- (#8c\x);
}
\end{scope}
}
% This function draws the lifeweel
%\lifeweel{levels}{grid}{number of features}{feature_name/quantity}[anchor angle][numbers direction in degrees][relative position](ID);
\lifeweel{10}{10}{8}{
Money/10,
Entertainment/10,
Romance/10,
Presonal Growth/10,
Friends {\&} Family/10,
Financial/10,
Spiritual/10,
Health/10
}[45][180](0,0)(1);
\ColourTransitionCircle[inner=0,outer=8,angle=40]{red,yellow,blue,blue,green}
\draw (0,0)circle (8);
\tikzset{
d1/.pic={
\foreach \t in {10,55,100,145,190,235,280,325} {
\draw[fill, red,thick] (\t:9) circle (0.5cm);
}
}
}
\tikzset{
d2/.pic={
\foreach \t in {22.5,67.5,112.5,157.5,202.5,247.5,292.5,337.5} {
\draw[fill, blue,thick] (\t:9) circle (0.5cm);
}
}
}
\tikzset{
d3/.pic={
\foreach \t in {35,80,125,170,215,260,305,350} {
\draw[fill,orange,thick] (\t:9) circle (0.5cm);
}
}
}
\tikzset{
d4/.pic={\node[circle,draw,minimum size=5cm,
text=white,
path picture={
\node at (path picture bounding box.center){
\includegraphics[scale=1]{example-image-a}
};
}]{};}
}
\pic at (0,0) {d1};
\pic at (0,0) {d2};
\pic at (0,0) {d3};
\pic at (0,0) {d4};
\end{tikzpicture}
\end{document}
and the output is:
Just for fun. An attempt to "reinvent the wheel". The purpose of this exercise is not to answer the question, i.e. I think the tick should go to ferahfeza's nice answer. The purpose here is to
- eliminate redundancies. E.g. the number of features is already determined by the number of entries of the feature list.
- making things more TikZy. Instead of defining a command with 8 arguments it might be more appropriate to focus on the relevant data only, and to store all the parameters in pgf keys. This has also the advantage that, if someone else is to customize this, something like
\pgfkeysvalueof{/tikz/life wheel/radius}
may be easier to interpret than#1
, say. And it is easy to add more possibilities without changing the syntax of the command. - remove unnecessary packages. There is no need to load
xifthen
, TikZ allows on to distinguish all the cases with built in features. (And\usepackage{pgfmath}
does not have to be loaded.)
This answer cooks the command down to
\LifeWeel[radius=9,outer image radius=0.8,%
colors={"red","blue","magenta","purple","orange","green"}
]{"example-image-duck","example-image-a","example-image-b","example-image-c"}{%
Money/10,
Entertainment/10,
Romance/10,
Personal Growth/10,
Friends {\&} Family/10,
Financial/10,
Spiritual/10,
Health/10}
where the first argument is the list of the graphics that is to be included (the first one is the one in the middle), and the second argument is the list of features. Everything else can be controlled by options that are passed as zeroth argument.
\documentclass[border=20pt]{standalone}
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{decorations.text,shadings}
\renewcommand*\familydefault{\sfdefault} % Set font to serif family
% smuggling from https://tex.stackexchange.com/a/470979/121799
\newcounter{smuggle}
\DeclareRobustCommand\smuggleone[1]{%
\stepcounter{smuggle}%
\expandafter\global\expandafter\let\csname smuggle@\arabic{smuggle}\endcsname#1%
\aftergroup\let\aftergroup#1\expandafter\aftergroup\csname smuggle@\arabic{smuggle}\endcsname
}
\DeclareRobustCommand\smuggle[2][1]{%
\smuggleone{#2}%
\ifnum#1>1
\aftergroup\smuggle\aftergroup[\expandafter\aftergroup\the\numexpr#1-1\aftergroup]\aftergroup#2%
\fi
}
\begin{document}
\begin{tikzpicture}[
% Environment Cfg
font=\Large,
scale=1,
% Styles
]
\tikzset{life wheel/.cd,
radius/.initial=10,
outer image radius/.initial=1,
inner image radius/.initial=2,
outer image parameters/.initial={width=2.5cm},
inner image parameters/.initial={width=5cm},
Separator/.style={thick, color=black!50},
Border/.style={line width=1pt,color=red!60,shading=color wheel},
colors/.initial={}
}
% lifeweel from many codes arround TEX.SE
%Variables: 1:images, 2:image 3:number of features 4: Feature_name/quantity
% 5: anchor aling 6: numbers position 7:Relative position 8:ID
\newcommand\LifeWeel[3][]{%
\def\imglst{{#2}}
\tikzset{life wheel/.cd,#1}
\edef\LstColors{\pgfkeysvalueof{/tikz/life wheel/colors}}
\edef\NumColors{0}
\foreach \X [count=\Y starting from 1] in \LstColors
{\edef\NumColors{\Y}
\smuggle[2]{\NumColors}}
\foreach \X [count=\Y starting from 0] in {#2}
{\edef\NumImages{\Y}
\smuggle[2]{\NumImages}}
\foreach \X [count=\Y] in {#3}
{\edef\NumFeatures{\Y}
\smuggle[2]{\NumFeatures}}
%Drawing the border
\draw[life wheel/Border] (0,0) circle [radius=\pgfkeysvalueof{/tikz/life wheel/radius}];
%Drawing features separations.
\ifnum\NumColors>1
\foreach \m [count=\i] in {1,...,\NumFeatures}{
\pgfmathtruncatemacro{\myi}{mod(\i-1,\NumColors)}
\pgfmathsetmacro{\mycolor}{{\LstColors}[\myi]}
\draw[life wheel/Separator,top color=\mycolor!75!black,
bottom color=\mycolor,shading angle={-90+(360/\NumFeatures)*(\i-0.5)}] (0,0) -- (360/\NumFeatures*\i:\pgfkeysvalueof{/tikz/life wheel/radius})
arc({(360/\NumFeatures)*\i}:{(360/\NumFeatures)*(\i-1)}:\pgfkeysvalueof{/tikz/life wheel/radius})
-- cycle;}
\else
\foreach \m [count=\i] in {0,1,...,\NumFeatures}{
\draw[life wheel/Separator] (0,0) -- (360/\NumFeatures*\i:\pgfkeysvalueof{/tikz/life wheel/radius});}
\fi
%Drawing the names
\foreach \o/\p [count=\j] in {#3}{
\pgfmathtruncatemacro{\myint}{ifthenelse(sin(360/\NumFeatures*\j)<0,-1,1)}
\ifnum\myint<0% True
\path[%Reverse
decoration={
raise = -0.8ex,
text along path,
text = {|\huge|\o},
text align = center,
reverse path
},
decorate
]
(360/\NumFeatures*\j:\pgfkeysvalueof{/tikz/life wheel/radius}+0.7) arc (360/\NumFeatures*\j:360/\NumFeatures*(\j-1):\pgfkeysvalueof{/tikz/life wheel/radius}+0.7);%\path
\else%False
\path[%Normal
decoration={
raise = -0.8ex,
text along path,
text = {|\huge|\o},
text align = center
},
decorate
]
(360/\NumFeatures*\j:\pgfkeysvalueof{/tikz/life wheel/radius}+0.7) arc (360/\NumFeatures*\j:360/\NumFeatures*(\j-1):\pgfkeysvalueof{/tikz/life wheel/radius}+0.7); %Path
\fi
\foreach \X in {1,...,\NumImages}
{\pgfmathsetmacro{\tmp}{360/\NumFeatures*\j+((1-2*\X)/(2*\NumImages))*360/\NumFeatures}
\pgfmathsetmacro{\imgname}{\imglst[\X]}
\begin{scope}
\clip (\tmp:{\pgfkeysvalueof{/tikz/life
wheel/radius}-1.1*\pgfkeysvalueof{/tikz/life wheel/outer image radius}})
circle[radius=\pgfkeysvalueof{/tikz/life wheel/outer image radius}];
\node[rotate={\tmp-\myint*90}] at
(\tmp:{\pgfkeysvalueof{/tikz/life wheel/radius}-1.1*\pgfkeysvalueof{/tikz/life wheel/outer image radius}})
{\edef\temp{\noexpand\includegraphics[\pgfkeysvalueof{/tikz/life wheel/outer image parameters}]{\imgname}}
\temp};
\end{scope}
}
}
\begin{scope}
\pgfmathsetmacro{\imgname}{\imglst[0]}
\clip (0,0) circle[radius=\pgfkeysvalueof{/tikz/life wheel/inner image radius}];
\node at (0,0)
{\edef\temp{\noexpand\includegraphics[\pgfkeysvalueof{/tikz/life wheel/inner image parameters}]{\imgname}}
\temp};
\end{scope}
}
% This function draws the lifeweel
%\LifeWeel{figures}{list of features in the form feature_name/quantity}
\LifeWeel[radius=9,outer image radius=0.8,%
colors={"red","blue","magenta","purple","orange","green"}
]{"example-image-duck","example-image-a","example-image-b","example-image-c"}{%
Money/10,
Entertainment/10,
Romance/10,
Personal Growth/10,
Friends {\&} Family/10,
Financial/10,
Spiritual/10,
Health/10}
\end{tikzpicture}
\end{document}
If you leave the color list out, i.e. do
\LifeWeel[radius=9,outer image radius=0.8,%
%colors={"red","blue","magenta","purple","orange","green"}
]{"example-image-duck","example-image-a","example-image-b","example-image-c"}{%
Money/10,
Entertainment/10,
Romance/10,
Personal Growth/10,
Friends {\&} Family/10,
Financial/10,
Spiritual/10,
Health/10}
what I originally thought the question was about