Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Setting more shapes in diagram (Read 1987 times)
Silvia88
Full Member
***
Offline


I Love MindFusion!

Posts: 121
Joined: Aug 31st, 2015
Setting more shapes in diagram
Aug 31st, 2015 at 4:23pm
Print Post  
Hi,
Is it possible to set more than one shape when touching the diagram? I want to draw both rectangle and rhombus but touching the screen it draws a rectangle and then only rhombus while I want to draw rectangles and rhombus according to the user's needs.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Setting more shapes in diagram
Reply #1 - Sep 1st, 2015 at 11:43am
Print Post  
Following discussion from previous thread, here's a method to convert free-drawings to some set of standard shapes, however using a custom class instead of unconnected links:

Code
Select All
diagramView.setBehavior(Behavior.Custom);
diagramView.setCustomNodeType(FreeDrawTool.class);

diagram.addDiagramListener(new DiagramAdapter()
{
	@Override
	public void nodeCreated(NodeEvent e)
	{
		DiagramNode node = e.getNode();
		if (node instanceof FreeDrawTool)
		{
			FreeDrawTool freeDraw = (FreeDrawTool)node;
			ShapeNode replacement = freeDraw.standardShapeReplacement(
				new Shape[]
				{
					Shape.fromId("Rectangle"),
					Shape.fromId("Decision")
				});

			if (replacement != null)
			{
				diagram.getNodes().remove(freeDraw);
				diagram.getNodes().add(replacement);
				diagramView.cancelDrag();
			}
			else
			{
				// replace with default shape or leave free-drawing?
			}
		}
	}
});

class FreeDrawTool extends DiagramNode
{
	ArrayList<PointF> points = new ArrayList<PointF>();

	@Override
	public void draw(Canvas g, RenderOptions options)
	{
		Paint paint = new Paint();
		paint.setStyle(Paint.Style.STROKE);
		paint.setColor(android.graphics.Color.BLACK);
		paint.setStrokeWidth(1);

		for (int p = 0; p < points.size() - 1; p++)
		{
			PointF point1 = points.get(p);
			PointF point2 = points.get(p + 1);
			g.drawLine(point1.x,  point1.y,  point2.x,  point2.y, paint);
		}
	}

	@Override
	protected void drawShadow(Canvas g, RenderOptions options)
	{
	}

	@Override
	protected void startCreate(PointF org)
	{
		super.startCreate(org);
		points.add(org);
	}

	@Override
	protected void updateCreate(PointF current)
	{
		super.updateCreate(current);
		points.add(current);
	}

	@Override
	protected boolean allowCreate(PointF current, InteractionState ist)
	{
		return true;
	};

	ShapeNode standardShapeReplacement(Shape[] shapes)
	{
		RectF bounds = calcBounds();

		Shape bestShape = null;
		double bestDeviation = Double.MAX_VALUE;
		final double maxDeviation = 20;

		ShapeNode testNode = new ShapeNode();
		testNode.setBounds(bounds);

		for (Shape shape : shapes)
		{
			testNode.setShape(shape);

			double deviation = 0;
			for (PointF point : points)
			{
				PointF nearest = testNode.getNearestBorderPoint(point);
				deviation += Utilities.distance(point,  nearest);
			}
			deviation /= points.size();

			if (deviation < bestDeviation)
			{
				bestShape = shape;
				bestDeviation = deviation;
			}
		}

		testNode.setShape(bestShape);
		return bestDeviation < maxDeviation ? testNode : null;
    }

	RectF calcBounds()
	{
		PointF pt1 = points.get(0);
		PointF pt2 = points.get(points.size()-1);

		float l = Math.min(pt1.x, pt2.x);
		float r = Math.max(pt1.x, pt2.x);
		float t = Math.min(pt1.y, pt2.y);
		float b = Math.max(pt1.y, pt2.y);

		for (int i = 1; i < points.size() - 1; ++i)
		{
			l = Math.min(l, points.get(i).x);
			t = Math.min(t, points.get(i).y);
			r = Math.max(r, points.get(i).x);
			b = Math.max(b, points.get(i).y);
		}
		return new RectF(l, t, r, b);
	}
} 



It looks cute but gets tiresome if you have to draw a lot; I think users will prefer selecting a default shape and drawing with single swipe instead of having to trace shape outlines.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint