Exemple #1
0
LAYOUTEVENT CGraphLeeLayoutImpl::pulse(const GraphTypes::RectF & extent)
{
	size_t verticy_count = m_meta.GetVisibleUnpinnedVertexCount(m_graph, m_canvas);

	if (verticy_count > 1)
	{
		GraphTypes::PointF vp;
		LeeRoutePlanner* plannerLee;

		// GraphTypes::SizeF gridSize;

		//gridSize.Width=32.0;
		//gridSize.Height=32.0;

		plannerLee=LeeRoutePlanner::Create(); //gridSize);
		assert(plannerLee);

		plannerLee->BeginAddPoints();

		for(StlLinked<IVertexIterator> itr = m_graph->GetUserVertexIterator(new MetaStateSkipper(m_meta, m_canvas, TRISTATE_TRUE, TRISTATE_FALSE)); itr->IsValidItem(); itr->NextItem())
		{
			CComPtr<IGraphVertex> vertex = itr->Get();
			CComPtr<IRenderer> ir=m_canvas->GetRenderer(vertex);
			ir->GetPosition(vp);
			plannerLee->AddPoint(vp, &vp);
			ir->SetPosition(vp);
		}

		plannerLee->EndAddPoints();

		IGraphEdgeVector edges;
		m_graph->GetEdges(edges);
		for (IGraphEdgeVector::iterator itr = edges.begin(); itr != edges.end(); ++itr)
		{
			IGraphEdge * edge = *itr;
			IGraphVertex * from = edge->GetSource();
			IGraphVertex * to = edge->GetTarget();
			GraphTypes::PointF start, end;
			GraphTypes::PointFVector path;
			CComPtr<IRenderer> irf=m_canvas->GetRenderer(from);
			CComPtr<IRenderer> irt=m_canvas->GetRenderer(to);
			CComQIPtr<IEdgeRenderer> ire=m_canvas->GetRenderer(edge);

			irf->GetPosition(start);
			irt->GetPosition(end);

			if ( plannerLee->GetShortestPath( 
				 start,
				 end,
				 path ) )
			{
				ire->SetPoints(path);
			}
		}

		plannerLee->Dispose();
	}

	return LAYOUTEVENT_FINISHED;
}
//relaxEdges is more like tense edges up.  All edges pull nodes closes together;
void CGraphTouchgraphLayoutImpl::relaxEdges() 
{
    std::map<unsigned,IGraphVertex*> dupes;

    for (CComPtr<IEdgeIterator> itr = m_graph->GetEdgeIterator(); itr->IsValidItem() == true && !m_halt; itr->NextItem())
    {
        IGraphEdge * edge = itr->Get();
        if (m_meta.IsVisible(edge))
        {
            IGraphVertex* s = edge->GetSource();
            IGraphVertex* t = edge->GetTarget();
//TODO Identical to this edge pruning algo is used also in neato.cpp. Isolate into the 
//method when changing headers will be less painful
            CComPtr<IGraphSubgraph> ss=s->GetParent();
            CComPtr<IGraphSubgraph> st=t->GetParent();
            ATLASSERT(ss && st);

            bool addedge=true;
            bool sinsg=false, tinsg=false;

            unsigned shash, thash;
            if(ss->GetID()!=ROOT_ID) // edge for vertex that is not in the root graph
            {
                sinsg=true;
                // see if the other side is in the map
                if(dupes.find(t->GetID().GetHash())==dupes.end())
                {
                    dupes[t->GetID().GetHash()]=t;
                    shash=ss->GetID().GetHash();
                }
                else
                    addedge=false;
            }
            else
                shash=s->GetID().GetHash();

            if(addedge && st->GetID()!=ROOT_ID) // edge for vertex that is not in the root graph
            {
                tinsg=true;
                // see if the other side is in the map
                if(dupes.find(s->GetID().GetHash())==dupes.end())
                {
                    dupes[s->GetID().GetHash()]=s;
                    thash=st->GetID().GetHash();
                }
                else
                    addedge=false;
            }
            else
                thash=t->GetID().GetHash();
            
            if(sinsg && tinsg) // skip edges connecting vertices inside subgraph 
                addedge=false; 

            if(!addedge)
                continue;

            PointF posTo;
            IRenderer * ir = m_canvas->GetRenderer(t);
            if(ir)
            {
                ir->GetPosition(posTo);
            }
            PointF posFrom;
            ir = m_canvas->GetRenderer(s);
            if(ir)
            {
                ir->GetPosition(posFrom);
            }

            PointF vP(posTo.x - posFrom.x, posTo.y - posFrom.y);			
            float len = sqrt(vP.x * vP.x + vP.y * vP.y);

            //PointF
            float dx = vP.x * rigidity;  //rigidity makes edges tighter
            float dy = vP.y * rigidity;

            dx /= 150.0f * 100;
            dy /= 150.0f * 100;

            // Edges pull directly in proportion to the distance between the nodes. This is good,
            // because we want the edges to be stretchy.  The edges are ideal rubberbands.  They
            // They don't become springs when they are too short.  That only causes the graph to
            // oscillate.

//			ATLASSERT(dx < 1 && dy < 1);

            //if (m_justMadeLocal[to->GetID()] || !m_justMadeLocal[from->GetID()]) 
            //{
            //	m_dv[to->GetID()].x -= dx * len;
            //	m_dv[to->GetID()].y -= dy * len;
            //} 
            //else 
            {
                m_dv[t->GetID()].x -= dx * len / 10;
                m_dv[t->GetID()].y -= dy * len / 10;
            }

            //if (m_justMadeLocal[from->GetID()] || !m_justMadeLocal[to->GetID()]) 
            //{
            //	m_dv[from->GetID()].x += dx * len;
            //	m_dv[from->GetID()].y += dy * len;
            //} 
            //else 
            {
                m_dv[s->GetID()].x += dx * len / 10;
                m_dv[s->GetID()].y += dy * len / 10;
            }
        }
    }
}