9

Similar to this post RFP Process on a Graph I tried to represent a fleet retirement plan. Basically, I am trying to have a 3 to 4 year visual plan of my fleet and when each piece of equipment shall retire. As shown in the graph below, equipment AS retired 01-Feb-15 and equipment AE will retire 15-Nov-16. It will be nice that I put the equipment, its retirement date, and color like

\equip{AS}{01-Feb-15}{red} or any date format and the dot gets plotted.

Note: Any other idea to have the visual view is welcomed.

enter image description here

Here is my trial:

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}

\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{decorations.text}


\begin{document}

\begin{figure}[!htb]
\centering
\scalebox{.75}{
  \definecolor{color1}{RGB}{25,229,0}
  \definecolor{color2}{RGB}{51,204,0}
  \definecolor{color3}{RGB}{76,178,0}
  \definecolor{color4}{RGB}{102,153,0}
  \definecolor{color5}{RGB}{127,127,0}
  \definecolor{color6}{RGB}{153,102,0}
  \definecolor{color7}{RGB}{255,0,0}
  \definecolor{svacolor}{RGB}{24,33,110}
  \newcommand*\mybs{.55cm}
  \newcommand*\radiuss{\mybs+.1cm*.55cm}
  \newcommand*\mcs{.55cm}
  \newcommand*\mybf{.35cm}
  \newcommand*\radiusf{\mybf+.1cm*.55cm}
  \newcommand*\mcf{.55cm}
  \newcommand*\myangle{36}
  \tikzset{
  deco/.style n args=2{
       postaction={decorate, decoration={text along path, text=#2, text align=center, text color=#1},},
  },
  mini node/.style={circle, draw, fill=gray, inner sep=.5mm}}
   \begin{tikzpicture}
      \foreach \i/\j [count=\k from=0] in  {2017/color7,2016/color6,2015/color5}
      \draw [\j, deco={\j}{\i},  thick] (0,-\mybf-3mm*\mcf+\k*.5mm*\mcf) arc (270:-120:\mybf+3mm*\mcf-\k*.5mm*\mcf) ;
      \node [draw, fill=color1, circle, inner sep=.2mm] (a) at (0,0) {};
      \foreach \i/\j/\m/\c [count=\k from 1] in {330/6/Dec/svacolor, 300/6/Nov/svacolor, 270/6/Oct/svacolor, 240/6/Sep/svacolor, 210/6/Aug/svacolor, 180/6/Jul/svacolor, 150/6/Jun/svacolor, 120/6/May/svacolor, 90/6/Apr/svacolor, 60/6/Mar/svacolor, 30/6/Feb/svacolor, 0/6/Jan/svacolor}
      {
          % \draw [thin, gray!40] (a) -- (\i:\radiusf+89);
          \draw[\c] (\i:\mybf+3mm*\mcf-\j*.5mm*\mcf) node [mini node, inner sep=.2mm] {} -- (\i:\mybf+3mm*\mcf+.5mm*\mcf) coordinate (a\k);
          \ifnum\i<270 \ifnum\i>90
          \node[\c] (company \k) [anchor=south east] at (a\k)  {\m};
          \draw[\c] (company \k.south east) -- (company \k.south west) node [mini node, \c] {};
          \else
          \node[\c] (company \k) [anchor=south west] at (a\k)  {\m};
          \draw[\c] (company \k.south west) -- (company \k.south east) node [mini node, \c] {};
          \fi
          \else
          \node[\c] (company \k) [anchor=south west] at (a\k)  {\m};
          \draw[\c] (company \k.south west) -- (company \k.south east) node [mini node, \c] {};
          \fi
      }
    \end{tikzpicture}

}
\caption{Pleet Retirement Plan}
\label{fig:bulleye}
\end{figure} 
\end{document}
  • 1
    Wouldn't this be better as a spiral? so that there was no jump between Dec and Jan? – Thruston Dec 13 '15 at 23:08
8

Here's a version as a spiral (in Metapost).

Revised version

This implementation is a little more robust than the earlier one and lets you choose the start and end years.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

vardef day_number(expr Y,M,D) = 
  save y,m;
  y := Y-2016;
  m := M-3;
  forever:
    exitif m>=0;
    m := m+12;
    y := y-1;
  endfor
  forever:
    exitif m<12;
    m := m-12;
    y := y+1;
  endfor
  365*y + floor(y/4) + floor(.4+.6*m) + 30*m + D - 307
enddef;

vardef day_point(expr Y, M, D) = 
  day_number(Y,M,D)-S_first_day
enddef;

string month_name[];
month_name[1]  = "JANUARY";
month_name[2]  = "FEBRUARY";
month_name[3]  = "MARCH";
month_name[4]  = "APRIL";
month_name[5]  = "MAY";
month_name[6]  = "JUNE";
month_name[7]  = "JULY";
month_name[8]  = "AUGUST";
month_name[9]  = "SEPTEMBER";
month_name[10] = "OCTOBER";
month_name[11] = "NOVEMBER";
month_name[12] = "DECEMBER";

% draw string "s" along path p
vardef draw_along(expr s, p) =
   save c, t, wd;
   picture c; numeric t, wd, W;
   t = 0; W = 0;
   for i=1 upto length s:
      c := (substring (i-1,i) of s) infont defaultfont;
      wd := xpart urcorner c + 1; 
      draw c shifted (0,5) rotated angle direction t of p shifted point t of p;
      W := W + wd;
      t := arctime W of p;
   endfor
enddef;

vardef make_radar_calendar(expr alpha, omega) = 

    inner_radius := 100;
    year_gap := 36;
    S_first_day := day_number(alpha,1,1);
    S_final_day := day_number(omega,12,31);

    S = down scaled inner_radius 
          for i=1 upto S_final_day-S_first_day: 
            -- down scaled (inner_radius + i/1461*year_gap*4) rotated (-i/1461*1440) 
          endfor;

    drawoptions(withpen pencircle scaled 2pt withcolor .8 white);
    drawarrow S;
    drawoptions(withpen pencircle scaled 6pt withcolor white);
    for m=1 upto 12: 
      draw point day_point(alpha,m,1) of S
        -- point day_point(omega,m,1) of S;
    endfor

    drawoptions(withcolor .7 white);
    for m=1 upto 12:
      draw_along(substring (0,3) of month_name[m], subpath (day_point(alpha,m,24),0) of S);
      draw_along(                   month_name[m], subpath (day_point(omega,m,12),infinity) of S);
    endfor

    path se; se = superellipse(9 right, 7 up, 9 left, 7 down, 0.8);
    pair n;
    for y=alpha upto omega:
      for m=3 step 3 until 12:
        n := point day_point(y,m,1) of S;
        unfill se shifted n;
        draw   se shifted n;
        label(decimal (y mod 100),n);
      endfor
    endfor
    drawoptions();
enddef;

vardef mark_date@#(expr tag, Y, M, D) text _t= 
  interim dotlabeldiam := 5;
  interim labeloffset := 8;
  dotlabel@#(tag, point day_point(Y,M,D) of S) _t;
enddef;

beginfig(1);

path S;

defaultfont := "ptmr8r";
make_radar_calendar(2015,2025);

defaultfont := "phvr8r"; defaultscale := 1.414;
mark_date.ulft("AB", 2016,  4,  1);
mark_date.top("CD", 2016,  7,  5) withcolor red;
mark_date.lrt("EF", 2017, 11, 11) withcolor .67 blue;
mark_date.bot("GH", 2018,  1, 17);
mark_date.ulft("IJ", 2021,  6, 9);
mark_date.bot("You are here", year, month, day) withcolor .4 green; 

endfig;
end.

And here's another example (using data from here):

enter image description here

beginfig(2);
path S;
defaultfont := "ptmr8r";
make_radar_calendar(2015,2021);
interim ahangle := 180;
drawdblarrow subpath (day_point(2015,10,11), day_point(2015,12,05)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2016,01,17), day_point(2016,03,12)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2016,04,24), day_point(2016,06,18)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2016,10,09), day_point(2016,12,03)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2017,01,15), day_point(2017,03,11)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2017,04,23), day_point(2017,06,17)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2017,10,08), day_point(2017,12,02)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2018,01,14), day_point(2018,03,10)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2018,04,22), day_point(2018,06,16)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2018,10,07), day_point(2018,12,01)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2019,01,13), day_point(2019,03,09)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2019,04,28), day_point(2019,06,22)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2019,10,13), day_point(2019,12,07)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2020,01,19), day_point(2020,03,14)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2020,04,26), day_point(2020,06,20)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2020,10,11), day_point(2020,12,05)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2021,01,17), day_point(2021,03,13)) of S withpen pencircle scaled 1.3 withcolor .3 blue;
drawdblarrow subpath (day_point(2021,04,25), day_point(2021,06,19)) of S withpen pencircle scaled 1.3 withcolor .3 blue;

label.top("Dates of Term", origin);
label.bot("in Oxford", origin);

endfig;

Earlier versions

Some adjustments to the scale might be needed.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

vardef day_number(expr Y,M,D) = 
  save y,m;
  y := Y-2012;
  m := M-3;
  forever:
    exitif m>=0;
    m := m+12;
    y := y-1;
  endfor
  forever:
    exitif m<12;
    m := m-12;
    y := y+1;
  endfor
  365*y + floor(y/4) - floor(y/100) + floor(y/400) + floor(.4+.6*m) + 30*m + D - 307
enddef;

beginfig(1);  
path S; S = right scaled 100 for i=1 upto 4018: -- right scaled (100+i/10) rotated (i*1440/1461) endfor;

drawoptions(withcolor .6 white);
drawarrow S;
for m=1 upto 12: 
  draw point day_number(2013,m,1) of S
    -- point day_number(2023,m,1) of S;
endfor

picture m[]; numeric wd[]; i:=0;
forsuffixes $=JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC:
  i := i+1; m[i] = str $ infont "ptmr8r"; wd[i] = xpart urcorner m[i];
endfor
for i=1 upto 12:
  draw m[i] 
    if (3<i) and (i<10): rotated 180 shifted (80+3i+1/2wd[i],0)
                   else:             shifted (80+3i-1/2wd[i],0) 
    fi rotated (30i-15);
  endfor

for i=13 upto 22:
  draw decimal (2000+i) infont "ptmr8r" shifted (36.5i-372,2);
endfor

drawoptions();
vardef mark_date@#(expr tag, Y, M, D) text _t= 
  interim dotlabeldiam := 5;
  interim labeloffset := 8;
  dotlabel@#(tag, point day_number(Y,M,D) of S) _t;
enddef;

defaultfont := "phvr8r"; defaultscale := 1.414;
mark_date.top("AB", 2016,  4,  1);
mark_date.lft("CD", 2016,  7,  5) withcolor red;
mark_date.lrt("EF", 2016, 11, 11) withcolor .67 blue;
mark_date.rt("GH", 2018,  1, 17);
mark_date.ulft("IJ", 2021,  6, 9);
mark_date.bot("You are here", year, month, day) withcolor .4 green; 


endfig;
end.

You might prefer to use different colours for the grid: here's one with different colours for odd numbered years.

enter image description here

This is produced by changing the line

drawarrow S;

into

for i=1 upto 11:
  draw subpath(365.25i-365.25,365.25i) of S withcolor .5[if odd i:red else:blue fi,white];
endfor
drawarrow subpath ( 4015, infinity) of S withcolor .5[red,white];

and changing the rotation of the month labels from 30i-15 to 30i-30.

  • This is nice. It will be nicer if you can make each year with different color so it becomes easy for the eyes to spot the retirement date of the equip right away. Thx. – OOzy Pal Dec 14 '15 at 17:20
  • One more thing that the months are not aligned with the lines. – OOzy Pal Dec 14 '15 at 17:31
  • Putting the month labels in the middle of the relevant month was a deliberate choice, but you can just adjust the amount of rotation as desired; change the -15 part where it says rotated (30i-15). – Thruston Dec 14 '15 at 17:47
  • Yes, drawing the spiral in multicolours would be nice, and not hard. I'll add another version. – Thruston Dec 14 '15 at 17:48
  • How I can make it starts at 2015 and ends at 2025? I tried to change the numbers and I got messed up graph. Also, how can I make each year with different color for the circle and have the numbers (2015, etc.) matches the circles color? – OOzy Pal Dec 14 '15 at 21:02
11

Here's a very simple version. It has the core functionality, and could probably improved to be more versatile (distance of the year rings, replace the hardcoded 2016 with the lowest year needed...). Also, it just divides each month in 31 segments, so for 28/29/30 day months it draws the dots slightly to early, try e.g. the 28th February 2017.

Code

\documentclass[tikz, border=2mm]{standalone}
\usetikzlibrary{arrows}

\begin{document}

\newcommand{\retire}[5][black]%
% [options], name, year, month, day
{   \pgfmathsetmacro{\r}{(#3-2016)/2+2.5}
    \pgfmathsetmacro{\a}{(#4-1)*30+#5*30/31}
    \fill[#1] (\a:\r) circle (0.07);
    \node[#1,circle,inner sep=1pt,fill=white,opacity=0.75,text opacity=1] at (\a:\r-0.4) {#2};
}

\begin{tikzpicture}
    \foreach \m [count=\c] in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Okt,Nov,Dec}
    {   \pgfmathsetmacro{\d}{ifthenelse(and(\c>4,\c<11),-1,1)}
        \draw[*-*] (\c*30-30:0.3) -- (\c*30-30:5) -- ++ (\d,0) node[above, pos=0.5] {\m};
    }
    \foreach \y in {2016,...,2019}
    { \draw ({(\y-2016)/2+2.5},0) arc (0:360:{(\y-2016)/2+2.5}) node[sloped, pos=1/24, above, font=\tiny] {\y};
    }

    \retire{AP}{2016}{8}{12}
    \retire[magenta]{AD}{2017}{9}{19}
    \retire[blue!50]{AR}{2018}{11}{18}
    \retire[green!50!black, font=\bf]{AB}{2019}{10}{03}
\end{tikzpicture}

\end{document}

Output

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.