Example #1
0
      function(
        { runningDimensions, topLeftCorner, bottomRightCorner },
        entity: PvjsonSingleFreeNode | PvjsonEdge
      ) {
        const { zIndex } = entity;
        const zIndexIsFinite = isFinite(zIndex);
        const runningDimensionsZIndexIsFinite = isFinite(
          runningDimensions.zIndex
        );
        if (zIndexIsFinite && runningDimensionsZIndexIsFinite) {
          runningDimensions.zIndex = Math.min(zIndex, runningDimensions.zIndex);
        } else if (zIndexIsFinite) {
          runningDimensions.zIndex = zIndex;
        }

        if (isPvjsonEdge(entity)) {
          const points = entity.points;
          // If entity is an edge
          const firstPoint = points[0];
          const firstPointX = firstPoint.x;
          const firstPointY = firstPoint.y;
          const lastPoint = points[points.length - 1];
          const lastPointX = lastPoint.x;
          const lastPointY = lastPoint.y;
          topLeftCorner.x = Math.min(topLeftCorner.x, firstPointX, lastPointX);
          topLeftCorner.y = Math.min(topLeftCorner.y, firstPointY, lastPointY);
          bottomRightCorner.x = Math.max(
            bottomRightCorner.x,
            firstPointX,
            lastPointX
          );
          bottomRightCorner.y = Math.max(
            bottomRightCorner.y,
            firstPointY,
            lastPointY
          );
        } else {
          // If entity is a node
          topLeftCorner.x = Math.min(topLeftCorner.x, entity.x);
          topLeftCorner.y = Math.min(topLeftCorner.y, entity.y);
          bottomRightCorner.x = Math.max(
            bottomRightCorner.x,
            entity.x + entity.width
          );
          bottomRightCorner.y = Math.max(
            bottomRightCorner.y,
            entity.y + entity.height
          );
        }

        runningDimensions.x = topLeftCorner.x - padding - strokeWidth;
        runningDimensions.y = topLeftCorner.y - padding - strokeWidth;
        runningDimensions.width =
          bottomRightCorner.x - topLeftCorner.x + 2 * (padding + strokeWidth);
        runningDimensions.height =
          bottomRightCorner.y - topLeftCorner.y + 2 * (padding + strokeWidth);

        return { runningDimensions, topLeftCorner, bottomRightCorner };
      },
Example #2
0
/**
 * getOffsetAndOrientationScalarsAlongAxis
 *
 * @param relValue {number}
 * @param axis {string}
 * @param referencedEntity
 * @return {OffsetOrientationAndPositionScalarsAlongAxis}
 */
function getOffsetAndOrientationScalarsAlongAxis(
  positionScalar: number,
  relativeOffsetScalar: number,
  axis: "x" | "y",
  // TODO are we correctly handling the case of a group as the referenced
  // entity? Do we have the group width and height yet to properly calculate
  // this?
  referencedEntity: PvjsonNode
): OffsetOrientationAndPositionScalarsAlongAxis {
  let offsetScalar =
    relativeOffsetScalar *
    (axis === "x" ? referencedEntity.width : referencedEntity.height);
  // TODO WP536 has a referenced entity that lacks width/height. Why?
  // The referenced entity was a group.
  // Is the problem that the group was nested?
  // Or is it a problem with the order of evaluation of entities (trying to
  //   parse a dependent entity before its dependencies were parsed)?
  if (!isFinite(offsetScalar)) {
    throw new Error(
      `
			Got non-finite value ${offsetScalar} for offsetScalar
			along ${axis} axis for
			getOffsetAndOrientationScalarsAlongAxis(
				positionScalar=${positionScalar},
				relativeOffsetScalar=${relativeOffsetScalar},
				referencedEntity=
				${JSON.stringify(referencedEntity, null, "  ")}
			)
		`
    );
  }

  // orientationScalar here refers to the initial direction the edge takes as
  // it moves away from the entity to which it is attached.
  let orientationScalar;
  if (positionScalar === 0) {
    orientationScalar = -1;
  } else if (positionScalar === 1) {
    orientationScalar = 1;
  } else {
    orientationScalar = 0;
  }

  return { offsetScalar, orientationScalar, positionScalar };
}
Example #3
0
 .filter(dims => !isFinite(dims[1]));
Example #4
0
export function getGroupDimensions(
  padding: number,
  strokeWidth: number,
  containedEntities: PvjsonEntity[]
): NodeDimensions {
  if (containedEntities.length === 0) {
    console.warn(`Warning: Empty group observed.`);
    return {
      x: 0,
      y: 0,
      width: 0,
      height: 0,
      zIndex: 0
    };
  } else if (!isFinite(padding)) {
    throw new Error("Invalid padding value: ${padding}");
  } else if (!isFinite(strokeWidth)) {
    throw new Error("Invalid strokeWidth value: ${strokeWidth}");
  }
  const dimensions = containedEntities
    .filter(entity => isPvjsonSingleFreeNode(entity) || isPvjsonEdge(entity))
    .reduce(
      function(
        { runningDimensions, topLeftCorner, bottomRightCorner },
        entity: PvjsonSingleFreeNode | PvjsonEdge
      ) {
        const { zIndex } = entity;
        const zIndexIsFinite = isFinite(zIndex);
        const runningDimensionsZIndexIsFinite = isFinite(
          runningDimensions.zIndex
        );
        if (zIndexIsFinite && runningDimensionsZIndexIsFinite) {
          runningDimensions.zIndex = Math.min(zIndex, runningDimensions.zIndex);
        } else if (zIndexIsFinite) {
          runningDimensions.zIndex = zIndex;
        }

        if (isPvjsonEdge(entity)) {
          const points = entity.points;
          // If entity is an edge
          const firstPoint = points[0];
          const firstPointX = firstPoint.x;
          const firstPointY = firstPoint.y;
          const lastPoint = points[points.length - 1];
          const lastPointX = lastPoint.x;
          const lastPointY = lastPoint.y;
          topLeftCorner.x = Math.min(topLeftCorner.x, firstPointX, lastPointX);
          topLeftCorner.y = Math.min(topLeftCorner.y, firstPointY, lastPointY);
          bottomRightCorner.x = Math.max(
            bottomRightCorner.x,
            firstPointX,
            lastPointX
          );
          bottomRightCorner.y = Math.max(
            bottomRightCorner.y,
            firstPointY,
            lastPointY
          );
        } else {
          // If entity is a node
          topLeftCorner.x = Math.min(topLeftCorner.x, entity.x);
          topLeftCorner.y = Math.min(topLeftCorner.y, entity.y);
          bottomRightCorner.x = Math.max(
            bottomRightCorner.x,
            entity.x + entity.width
          );
          bottomRightCorner.y = Math.max(
            bottomRightCorner.y,
            entity.y + entity.height
          );
        }

        runningDimensions.x = topLeftCorner.x - padding - strokeWidth;
        runningDimensions.y = topLeftCorner.y - padding - strokeWidth;
        runningDimensions.width =
          bottomRightCorner.x - topLeftCorner.x + 2 * (padding + strokeWidth);
        runningDimensions.height =
          bottomRightCorner.y - topLeftCorner.y + 2 * (padding + strokeWidth);

        return { runningDimensions, topLeftCorner, bottomRightCorner };
      },
      {
        topLeftCorner: {
          x: Infinity,
          y: Infinity
        },
        bottomRightCorner: {
          x: 0,
          y: 0
        },
        runningDimensions: {
          zIndex: Infinity
        }
      } as {
        topLeftCorner: Corner;
        bottomRightCorner: Corner;
        runningDimensions: NodeDimensions;
      }
    ).runningDimensions;

  const propertiesToCheck = ["x", "y", "width", "height", "zIndex"];
  const nonFinites = propertiesToCheck
    .map(function(key) {
      return [[key], dimensions[key]];
    })
    .filter(dims => !isFinite(dims[1]));
  if (nonFinites.length > 0) {
    throw new Error(
      `Got a non-finite value(s):
			${JSON.stringify(fromPairs(nonFinites), null, "  ")}
			when calling
			getGroupDimensions(
				padding: ${padding},
				strokeWidth: ${strokeWidth},
				containedEntities: ${JSON.stringify(containedEntities, null, "  ")}
			)
			
			`
    );
  }

  return dimensions;
}
export function validateOrientation(orientation: Orientation): boolean {
  return !!orientation && isFinite(orientation[0]) && isFinite(orientation[1]);
}