Resources

Ishikawa / Fishbone / Cause & Effect Diagrams

 /****************************************************************/
 /*          S A S   S A M P L E   L I B R A R Y                 */
 /*                                                              */
 /*    NAME: ISHIKAWA                                            */
 /*   TITLE: Ishikawa / Fishbone / Cause & Effect Diagrams       */
 /* PRODUCT: QC                                                  */
 /*  SYSTEM: ALL                                                 */
 /*    KEYS: Ishikawa Diagrams,                                  */
 /*   PROCS: GANNO                                               */
 /*    DATA:                                                     */
 /*                                                              */
 /*     REF:                                                     */
 /*    MISC: This program performs all the calculations          */
 /*          necessary to draw an Ishikawa (ie fishbone, cause   */
 /*          and effect, stem and leaf) diagram with high        */
 /*          resolution color graphics.                          */
 /*                                                              */
 /*          NOTE: This program is NOT a stand-alone program.    */
 /*          The program is %INCluded in each of ISHIKAW1 and    */
 /*          ISHIKAW2 programs by associating a fileref          */
 /*          with this program.                                  */
 /*                                                              */
 /****************************************************************/


DATA DEFAULT;
 SET DEFAULT;
 DROP HSIZE VSIZE;
 SPACEPCT=0.25;  /* TEXTHT*SPACEPCT= SPACE BETWEEN LINES OF TEXT */
 CALL SYMPUT('SPACEPCT',PUT(SPACEPCT,5.4));
 HVRATIO=HSIZE/VSIZE;
 XSYS='3';
 YSYS='3';
 HSYS='3';
 N=_N_;

DATA TITLE;
 SET TITLE;
 RETAIN Y 99;
 RENAME TEXTHT=SIZE TITLE=TEXT FONT=STYLE;
 DROP DIFF LAGHT ALIGN;
 XSYS='3';
 YSYS='3';
 HSYS='3';
 FUNCTION='LABEL   ';
 ALIGN=UPCASE(ALIGN);
 IF ALIGN='R' THEN DO;
  X=100;
  POSITION='4';
  END;
  ELSE IF ALIGN='L' THEN DO;
        X=0;
        POSITION='6';
        END;
        ELSE DO;
         X=50;
         POSITION='5';
         END;
 ANGLE=0;
 ROTATE=0;
 LAGHT=LAG(TEXTHT);
 IF _N_=1 THEN DIFF=-0.5*TEXTHT;
  ELSE DIFF=-0.5*(LAGHT+2*&SPACEPCT*LAGHT+TEXTHT);
 Y+DIFF;

DATA FOOTNOTE;
 SET FOOTNOTE;
 N=_N_;

PROC SORT DATA=FOOTNOTE;
 BY DESCENDING N;

DATA FOOTNOTE;
 SET FOOTNOTE;
 RENAME TEXTHT=SIZE FOOTNOTE=TEXT FONT=STYLE;
 RETAIN Y 1;
 DROP DIFF LAGHT ALIGN;
 XSYS='3';
 YSYS='3';
 HSYS='3';
 FUNCTION='LABEL   ';
 ALIGN=UPCASE(ALIGN);
 IF ALIGN='C' THEN DO;
  X=50;
  POSITION='5';
  END;
  ELSE IF ALIGN='L' THEN DO;
        X=0;
        POSITION='6';
        END;
        ELSE DO;
         X=100;
         POSITION='4';
         END;
 ANGLE=0;
 ROTATE=0;
 LAGHT=LAG(TEXTHT);
 IF _N_=1 THEN DIFF=0.5*TEXTHT;
  ELSE DIFF=0.5*(TEXTHT+2*&SPACEPCT*TEXTHT+LAGHT);
 Y+DIFF;

DATA BORDER;
 SET BORDER;
 XSYS='3';
 YSYS='3';
 HSYS='3';
 X=  0; Y=  0; FUNCTION='MOVE    ';
 OUTPUT;
 X=  0; Y=100; FUNCTION='DRAW    ';
 OUTPUT;
 X=100; Y=100; FUNCTION='DRAW    ';
 OUTPUT;
 X=100; Y=  0; FUNCTION='DRAW    ';
 OUTPUT;
 X=  0; Y=  0; FUNCTION='DRAW    ';
 OUTPUT;

DATA EFFECT;
 SET EFFECT;
 DROP Y;
 N=_N_;
 FROMY=Y;
 TOY=Y;
 CALL SYMPUT('TRUNK',LEFT(PUT(N,4.)));
 CALL SYMPUT('TRUNKTH',PUT(TRUNKTH,10.2));
 CALL SYMPUT('FROMX',PUT(FROMX,10.2));
 CALL SYMPUT('FROMY',PUT(FROMY,10.2));

DATA CAUSES;
 IF _N_=1 THEN SET DEFAULT;
 SET CAUSES;
 DROP BLENGTH SLENGTH LLENGTH;
 RENAME BB=BLENGTH SS=SLENGTH LL=LLENGTH;
 N=_N_;
 BSL=UPCASE(BSL);
 SIDE=UPCASE(SIDE);
 IF BSL='BRANCH' THEN DO;
  BRANCH+1;
  STEM=0;
  LEAF=0;
  IF SIDE^=' ' THEN DO;
   IF SIDE='T' THEN INDEX=1;
    ELSE INDEX=-1;
   END;
  IF LENGTH=. THEN LENGTH=BLENGTH;
  BB=LENGTH;
  RETAIN INDEX BB;
  END;
 IF BSL='STEM' THEN DO;
  STEM+1;
  LEAF=0;
  IF LENGTH=. THEN LENGTH=SLENGTH;
  SS=LENGTH;
  RETAIN SS;
  END;
 IF BSL='LEAF' THEN DO;
  LEAF+1;
  IF LENGTH=. THEN LENGTH=LLENGTH;
  LL=LENGTH;
  RETAIN LL;
  END;

PROC SUMMARY DATA=CAUSES NWAY;
 CLASS BRANCH STEM;
 VAR LEAF;
 OUTPUT OUT=LEAF(DROP=_TYPE_ _FREQ_) MAX=MAXL;

DATA POSITION;
 MERGE CAUSES(KEEP=BSL BRANCH STEM LEAF) LEAF;
 BY BRANCH STEM;

PROC SUMMARY DATA=CAUSES NWAY;
 CLASS BRANCH;
 VAR STEM;
 OUTPUT OUT=STEM(DROP=_TYPE_ _FREQ_) MAX=MAXS;

DATA POSITION;
 MERGE POSITION STEM;
 BY BRANCH;

PROC SUMMARY DATA=CAUSES NWAY;
 VAR BRANCH;
 OUTPUT OUT=BRANCH(DROP=_TYPE_ _FREQ_) MAX=MAXB;

DATA POSITION;
 SET POSITION;
 IF _N_=1 THEN SET BRANCH;
 KEEP POSITION SIDE N INDEX;
 RENAME POSITION=PCT;
 RETAIN INDEX;
 N=_N_;
 IF BSL='BRANCH' THEN DO;
  POSITION=BRANCH/(MAXB+1);
  IF MOD(BRANCH,2)=0 THEN DO;
   SIDE='T';
   INDEX=1;
   END;
   ELSE DO;
    SIDE='B';
    INDEX=-1;
    END;
  END;
  ELSE IF BSL='STEM' THEN DO;
        POSITION=STEM/(MAXS+1);
        IF MOD(STEM,2)=0 THEN SIDE='R';
         ELSE SIDE='L';
        END;
        ELSE IF BSL='LEAF' THEN DO;
              POSITION=LEAF/(MAXL+1);
              IF MOD(LEAF,2)=0 THEN SIDE='T';
               ELSE SIDE='B';
              END;

DATA CAUSES;
 UPDATE POSITION CAUSES;
 BY N;

DATA EFFECT;
 UPDATE DEFAULT(OBS=1 RENAME=(DFLTCOL=COLOR)) EFFECT(OBS=1);
 BY N;

DATA EFFECT;
 SET EFFECT;
 KEEP XSYS YSYS HSYS FUNCTION X Y STYLE COLOR ANGLE ROTATE LINE
      SIZE TEXT POSITION;
 ARRAY NLINE {*} $ 80 T1-T5;
 ARRAY LINEY {*}      Y1-Y5;
 ARRAY PTX   {10}     PTX1-PTX10;
 ARRAY PTY   {10}     PTY1-PTY10;

 LENGTH STYLE $ 8;

 FILL=UPCASE(FILL);

 IF SHRINKX=. THEN SHRINKX=0;
 IF SHRINKY=. THEN SHRINKY=0;

 NLINES=0;
 DO I=1 TO DIM(NLINE);
  IF NLINE{I}^=' ' THEN NLINES+1;
  END;

 LENGTH=MAX(LENGTH(T1),LENGTH(T2),LENGTH(T3),LENGTH(T4),
            LENGTH(T5)                                   );

 TOTAL = NLINES*TEXTHT + (NLINES-1)*TEXTHT*SPACEPCT;
 START = TOY + 0.5*TOTAL;
 FINISH = TOY - 0.5*TOTAL;
 XU = TOX + 0.5*LENGTH*TEXTHT/HVRATIO - SHRINKX;
 YU = START + 0.5*TEXTHT - SHRINKY;
 XL = TOX - 0.5*LENGTH*TEXTHT/HVRATIO + SHRINKX;
 YL = FINISH - 0.5*TEXTHT + SHRINKY;

 CALL SYMPUT('TOX',PUT(XL,10.2));

 ADJUST=0.19*TEXTHT;
 DO I=1 TO DIM(NLINE);
  IF I <= NLINES THEN
   LINEY{I}=START-(I-1)*(1+SPACEPCT)*TEXTHT-0.5*TEXTHT+ADJUST;
   ELSE LINEY{I}=.;
  END;

 PTX1=XL-LWIDTH/HVRATIO;    PTY1=YU;
 PTX2=XL;                   PTY2=YU;
 PTX3=XL;                   PTY3=YL;
 PTX4=XU;                   PTY4=YL;
 PTX5=XU;                   PTY5=YU;
 PTX6=XL-LWIDTH/HVRATIO;    PTY6=YU;
 PTX7=XL-LWIDTH/HVRATIO;    PTY7=YU+LWIDTH;
 PTX8=XU+LWIDTH/HVRATIO;    PTY8=YU+LWIDTH;
 PTX9=XU+LWIDTH/HVRATIO;    PTY9=YL-LWIDTH;
 PTX10=XL-LWIDTH/HVRATIO;   PTY10=YL-LWIDTH;

 IF FILL^='S' THEN DO;
  X=PTX{1};
  Y=PTY{1};
  LINE=1;
  STYLE='S       ';
  FUNCTION='POLY    ';
  OUTPUT;
  FUNCTION='POLYCONT';
  DO I=2 TO DIM(PTX);
   X=PTX{I};
   Y=PTY{I};
   OUTPUT;
   END;
  IF FILL^='E' THEN DO;
   X=XL;
   Y=YL;
   FUNCTION='MOVE    ';
   OUTPUT;
   X=XU;
   Y=YU;
   LINE=0;
   STYLE=FILL;
   FUNCTION='BAR     ';
   OUTPUT;
   END;
  END;
  ELSE DO;
   X=XL-LWIDTH/HVRATIO;
   Y=YL-LWIDTH;
   FUNCTION='MOVE    ';
   OUTPUT;
   X=XU+LWIDTH/HVRATIO;
   Y=YU+LWIDTH;
   LINE=0;
   STYLE='S       ';
   FUNCTION='BAR     ';
   OUTPUT;
   END;

 XL = XL - LWIDTH/HVRATIO;

 WHEN='A';

 ANGLE=0;
 ROTATE=0;
 SIZE=TEXTHT;
 STYLE=FONT;
 POSITION='5';
 FUNCTION='LABEL   ';
 DO LINE=1 TO NLINES;
  X=TOX;
  Y=LINEY{LINE};
  TEXT=NLINE{LINE};
  OUTPUT;
  END;

 PTX1=FROMX;
 PTY1=FROMY;
 PTX2=XL;
 PTY2=TOY;

 LWIDTH=&TRUNKTH;

 A=ALENGTH*AWIDTH+LWIDTH/2;
 B=ALENGTH+LWIDTH/2/AWIDTH;
 C=LWIDTH/2/AWIDTH;
 D=LWIDTH/2;

 X=PTX1;
 Y=PTY1+0.5*LWIDTH;
 LINE=1;
 STYLE='S       ';
 FUNCTION='POLY    ';
 OUTPUT;

 X=PTX1;
 Y=PTY1-0.5*LWIDTH;
 FUNCTION='POLYCONT';
 OUTPUT;

 IF PTX2 < PTX1 THEN INDEX1=-1;
  ELSE INDEX1=1;

 X=PTX2-(INDEX1*C)/HVRATIO;
 Y=PTY2-D;
 OUTPUT;

 X=PTX2-(INDEX1*C)/HVRATIO;
 Y=PTY2+D;
 OUTPUT;

 X=PTX2;
 Y=PTY2;
 FUNCTION='POLY    ';
 OUTPUT;

 X=PTX2-INDEX1*(B)/HVRATIO;
 Y=PTY2+INDEX1*A;
 FUNCTION='POLYCONT';
 OUTPUT;

 X=PTX2-INDEX1*C/HVRATIO;
 Y=PTY2;
 OUTPUT;

 X=PTX2-INDEX1*B/HVRATIO;
 Y=PTY2-INDEX1*A;
 OUTPUT;
RUN;


DATA CAUSES;
 SET CAUSES;
 DROP TOY;

  IF COLOR=' ' THEN COLOR=DFLTCOL;

  ADJUST=0.19*TEXTHT;

  IF BSL='BRANCH' THEN DO;
   TOX=&FROMX+PCT*(&TOX-&FROMX);
   TOY=&FROMY;
   FROMX=TOX-LENGTH/TAN(ANGLE*ARCOS(0)/90);
   FROMY=TOY+INDEX*LENGTH;
   IF TEXT2=' ' THEN DO;
    XU = FROMX + 0.5*LENGTH(TEXT1)*TEXTHT/HVRATIO;
    YU = FROMY + TEXTHT;
    XL = FROMX - 0.5*LENGTH(TEXT1)*TEXTHT/HVRATIO;
    YL = FROMY - TEXTHT;
    TEXTY=FROMY+ADJUST;
    END;
    ELSE DO;
     XU = FROMX + 0.5*MAX(LENGTH(TEXT1),LENGTH(TEXT2))*
                  TEXTHT/HVRATIO;
     YU = FROMY + 0.5*SPACEPCT*TEXTHT + 1.5*TEXTHT;
     XL = FROMX - 0.5*MAX(LENGTH(TEXT1),LENGTH(TEXT2))*
                  TEXTHT/HVRATIO;
     YL = FROMY - 0.5*SPACEPCT*TEXTHT - 1.5*TEXTHT;
     TEXTY1=FROMY+0.5*TEXTHT*(1+SPACEPCT)+ADJUST;
     TEXTY2=FROMY-0.5*TEXTHT*(1+SPACEPCT)+ADJUST;
     END;
   END;

DATA CAUSES;
 SET CAUSES;
 BY BRANCH STEM LEAF;
 KEEP XSYS YSYS HSYS FUNCTION X Y STYLE COLOR ANGLE ROTATE LINE
      SIZE TEXT POSITION;

 ARRAY PTX {10} PTX1-PTX10;
 ARRAY PTY {10} PTY1-PTY10;

 FILL=UPCASE(FILL);

 ADJUST=0.19*TEXTHT;
 ANGLE=0;
 ROTATE=0;
 SIZE=TEXTHT;
 STYLE=FONT;

 IF FIRST.BRANCH THEN DO;

  PTX1=XL-LWIDTH/HVRATIO;    PTY1=YU;
  PTX2=XL;                   PTY2=YU;
  PTX3=XL;                   PTY3=YL;
  PTX4=XU;                   PTY4=YL;
  PTX5=XU;                   PTY5=YU;
  PTX6=XL-LWIDTH/HVRATIO;    PTY6=YU;
  PTX7=XL-LWIDTH/HVRATIO;    PTY7=YU+LWIDTH;
  PTX8=XU+LWIDTH/HVRATIO;    PTY8=YU+LWIDTH;
  PTX9=XU+LWIDTH/HVRATIO;    PTY9=YL-LWIDTH;
  PTX10=XL-LWIDTH/HVRATIO;   PTY10=YL-LWIDTH;

  IF FILL^='S' THEN DO;
   X=PTX{1};
   Y=PTY{1};
   LINE=1;
   STYLE='S       ';
   FUNCTION='POLY    ';
   OUTPUT;
   FUNCTION='POLYCONT';
   DO I=2 TO DIM(PTX);
    X=PTX{I};
    Y=PTY{I};
    OUTPUT;
    END;
   IF FILL^='E' THEN DO;
    X=XL;
    Y=YL;
    FUNCTION='MOVE    ';
    OUTPUT;
    X=XU;
    Y=YU;
    LINE=0;
    STYLE=FILL;
    FUNCTION='BAR     ';
    OUTPUT;
    END;
   END;
   ELSE DO;
    X=XL-LWIDTH/HVRATIO;
    Y=YL-LWIDTH;
    FUNCTION='MOVE    ';
    OUTPUT;
    X=XU+LWIDTH/HVRATIO;
    Y=YU+LWIDTH;
    LINE=0;
    STYLE='S       ';
    FUNCTION='BAR     ';
    OUTPUT;
    END;
  X=FROMX;
  TEXT=TEXT1;
  POSITION='5';
  STYLE=XFONT;
  FUNCTION='LABEL   ';
  IF TEXT2=' ' THEN DO;
   Y=TEXTY;
   OUTPUT;
   END;
   ELSE DO;
    Y=TEXTY1;
    OUTPUT;
    TEXT=TEXT2;
    Y=TEXTY2;
    OUTPUT;
    END;

  IF INDEX=1 THEN DO;
   FROMY=YL - LWIDTH/2;
   PTY9=YL-LWIDTH;
   END;
   ELSE DO;
    FROMY=YU + LWIDTH/2;
    PTY9=YU+LWIDTH;
    END;
  TOY=&FROMY+INDEX*&TRUNKTH/2;

  PTX1=FROMX;
  PTY1=FROMY;
  PTX2=TOX;
  PTY2=TOY;
  LINK PALLEL;

  SLOPE=(FROMY-TOY)/(FROMX-TOX);
  INTERCPT=FROMY-SLOPE*FROMX;
  RETAIN TOY SLOPE INTERCPT PTY9;
  RETURN;
  END;

 IF FIRST.STEM & STEM>0 THEN DO;
  NODE=TOY+PCT*INDEX*ABS(PTY9-TOY);
  IF BSL='STEM' & SIDE=:'R' THEN TEXTPOS='6';
   ELSE TEXTPOS='4';
  INTX=(NODE-INTERCPT)/SLOPE;
  STEMTH=LWIDTH/(2*SIN(ABS(ATAN(SLOPE))));
  STEMPOS=NODE;
  IF TEXTPOS='4' THEN DO;
   PTX1=INTX-LENGTH;
   PTY1=NODE;
   PTX2=INTX-STEMTH;
   PTY2=NODE;
   LINK PALLEL;
   X=INTX-LENGTH-TEXTHT/2;
   POSITION=TEXTPOS;
   STYLE=XFONT;
   FUNCTION='LABEL   ';
   IF TEXT2^=' ' THEN DO;
    Y=NODE+0.5*TEXTHT*(1+SPACEPCT)+ADJUST;
    TEXT=TEXT1;
    OUTPUT;
    Y=NODE-0.5*TEXTHT*(1+SPACEPCT)+ADJUST;
    TEXT=TEXT2;
    OUTPUT;
    END;
    ELSE DO;
     Y=NODE+ADJUST;
     TEXT=TEXT1;
     OUTPUT;
     END;
   END;
   ELSE DO;
    PTX1=INTX+LENGTH;
    PTY1=NODE;
    PTX2=INTX+STEMTH;
    PTY2=NODE;
    LINK PALLEL;
    X=INTX+LENGTH+TEXTHT/2;
    POSITION=TEXTPOS;
    STYLE=XFONT;
    FUNCTION='LABEL   ';
    IF TEXT2^=' ' THEN DO;
     Y=NODE+0.5*TEXTHT*(1+SPACEPCT)+ADJUST;
     TEXT=TEXT1;
     OUTPUT;
     Y=NODE-0.5*TEXTHT*(1+SPACEPCT)+ADJUST;
     TEXT=TEXT2;
     OUTPUT;
     END;
     ELSE DO;
      Y=NODE+ADJUST;
      TEXT=TEXT1;
      OUTPUT;
      END;
    END;
  RETAIN INTX STEMTH STEMPOS TEXTPOS;
  RETURN;
  END;

 IF TEXTPOS='6' THEN DO;
  NODE=PCT*SLENGTH;
  IF BSL='LEAF' & SIDE='T' THEN DO;
   PTX1=INTX+NODE+LENGTH*COS(ABS(ATAN(SLOPE)));
   PTY1=STEMPOS+LENGTH*SIN(ABS(ATAN(SLOPE)));
   PTX2=INTX+NODE;
   PTY2=STEMPOS+LWIDTH/2;
   LINK PALLEL;
   X=INTX+NODE+LENGTH*COS(ABS(ATAN(SLOPE)));
   Y=STEMPOS+LENGTH*SIN(ABS(ATAN(SLOPE)))+TEXTHT2+ADJUST;
   POSITION=TEXTPOS;
   STYLE=FONT;
   SIZE=TEXTHT2;
   FUNCTION='LABEL   ';
   IF TEXT2^=' ' THEN DO;
    TEXT=TEXT2;
    OUTPUT;
    Y=STEMPOS+LENGTH*SIN(ABS(ATAN(SLOPE)))+TEXTHT2*(2+SPACEPCT)+
      ADJUST;
    END;
   TEXT=TEXT1;
   OUTPUT;
   END;
   ELSE DO;
    PTX1=INTX+NODE+LENGTH*COS(ABS(ATAN(SLOPE)));
    PTY1=STEMPOS-LENGTH*SIN(ABS(ATAN(SLOPE)));
    PTX2=INTX+NODE;
    PTY2=STEMPOS-LWIDTH/2;
    LINK PALLEL;
    X=INTX+NODE+LENGTH*COS(ABS(ATAN(SLOPE)));
    Y=STEMPOS-LENGTH*SIN(ABS(ATAN(SLOPE)))-TEXTHT2+ADJUST;
    POSITION=TEXTPOS;
    STYLE=FONT;
    SIZE=TEXTHT2;
    FUNCTION='LABEL   ';
    TEXT=TEXT1;
    OUTPUT;
    IF TEXT2^=' ' THEN DO;
     Y=STEMPOS-LENGTH*SIN(ABS(ATAN(SLOPE)))-TEXTHT2*(2+SPACEPCT)+
       ADJUST;
     TEXT=TEXT2;
     OUTPUT;
     END;
    END;
   END;
   ELSE DO;
    NODE=PCT*SLENGTH;
    IF BSL='LEAF' & SIDE='T' THEN DO;
     PTX1=INTX-NODE-LENGTH*COS(ABS(ATAN(SLOPE)));
     PTY1=STEMPOS+LENGTH*SIN(ABS(ATAN(SLOPE)));
     PTX2=INTX-NODE;
     PTY2=STEMPOS+LWIDTH/2;
     LINK PALLEL;
     X=INTX-NODE-LENGTH*COS(ABS(ATAN(SLOPE)));
     Y=STEMPOS+LENGTH*SIN(ABS(ATAN(SLOPE)))+TEXTHT2+ADJUST;
     POSITION=TEXTPOS;
     STYLE=FONT;
     SIZE=TEXTHT2;
     FUNCTION='LABEL   ';
     IF TEXT2^=' ' THEN DO;
      TEXT=TEXT2;
      OUTPUT;
      Y=STEMPOS
         +LENGTH*SIN(ABS(ATAN(SLOPE)))+TEXTHT2*(2+SPACEPCT)+ADJUST;
      END;
     TEXT=TEXT1;
     OUTPUT;
     END;
     ELSE DO;
      PTX1=INTX-NODE-LENGTH*COS(ABS(ATAN(SLOPE)));
      PTY1=STEMPOS-LENGTH*SIN(ABS(ATAN(SLOPE)));
      PTX2=INTX-NODE;
      PTY2=STEMPOS-LWIDTH/2;
      LINK PALLEL;
      X=INTX-NODE-LENGTH*COS(ABS(ATAN(SLOPE)));
      Y=STEMPOS-LENGTH*SIN(ABS(ATAN(SLOPE)))-TEXTHT2+ADJUST;
      POSITION=TEXTPOS;
      STYLE=FONT;
      SIZE=TEXTHT2;
      FUNCTION='LABEL   ';
      TEXT=TEXT1;
      OUTPUT;
      IF TEXT2^=' ' THEN DO;
       Y=STEMPOS-LENGTH*SIN(ABS(ATAN(SLOPE)))-TEXTHT2*(2+SPACEPCT)
         +ADJUST;
       TEXT=TEXT2;
       OUTPUT;
       END;
      END;
    END;

RETURN;
PALLEL:

 A=ALENGTH*AWIDTH+LWIDTH/2;
 B=ALENGTH+LWIDTH/2/AWIDTH;
 C=LWIDTH/2/AWIDTH;
 D=LWIDTH/2;

 IF PTX2-PTX1^=0 THEN THETA=-ATAN((PTY2-PTY1)/(PTX2-PTX1)/HVRATIO);
  ELSE THETA=ARCOS(0);

 X=PTX1+0.5*LWIDTH*SIN(THETA)/HVRATIO;
 Y=PTY1+0.5*LWIDTH*COS(THETA);
 LINE=1;
 STYLE='S       ';
 FUNCTION='POLY    ';
 OUTPUT;

 X=PTX1-0.5*LWIDTH*SIN(THETA)/HVRATIO;
 Y=PTY1-0.5*LWIDTH*COS(THETA);
 FUNCTION='POLYCONT';
 OUTPUT;

 IF PTX2 < PTX1 THEN INDEX1=-1;
  ELSE INDEX1=1;
 IF PTX2=PTX1 & PTY2 > PTY1 THEN DO;
  THETA=-THETA;
  INDEX2=-1;
  END;
  ELSE INDEX2=1;

 X=PTX2-(INDEX1*COS(-THETA)*C-INDEX2*SIN(-THETA)*D)/HVRATIO;
 Y=PTY2-(INDEX1*SIN(-THETA)*C+COS(-THETA)*D);
 FUNCTION='POLYCONT';
 OUTPUT;

 X=PTX2-(INDEX1*COS(-THETA)*C+INDEX2*SIN(-THETA)*D)/HVRATIO;
 Y=PTY2-(INDEX1*SIN(-THETA)*C-COS(-THETA)*D);
 FUNCTION='POLYCONT';
 OUTPUT;

 X=PTX2;
 Y=PTY2;
 FUNCTION='POLY    ';
 OUTPUT;

 X=PTX2-INDEX1*(COS(-THETA)*B+SIN(-THETA)*A)/HVRATIO;
 Y=PTY2+INDEX1*(COS(-THETA)*A-SIN(-THETA)*B);
 FUNCTION='POLYCONT';
 OUTPUT;

 X=PTX2-INDEX1*COS(-THETA)*C/HVRATIO;
 Y=PTY2-INDEX1*SIN(-THETA)*C;
 FUNCTION='POLYCONT';
 OUTPUT;

 X=PTX2-INDEX1*(COS(-THETA)*B-SIN(-THETA)*A)/HVRATIO;
 Y=PTY2-INDEX1*(COS(-THETA)*A+SIN(-THETA)*B);
 FUNCTION='POLYCONT';
 OUTPUT;
 RETURN;
RUN;