日期:2014-05-17  浏览次数:21083 次

jsp页面如何画线,折现,箭头等。
我有这样一个需求
web页面上有字符串 A1 ,A2, A3分别表示三个模块
点击A1,A2,A3会分别进入到A1 ,A2, A3的详细表示画面。
A1 ,A2, A3之间有调用关系,这种调用关系希望能够通过线和箭头标识出来。

例如  
  A1 A3
  A2
  A4

A1调用A2,A2调用A4,所以A1与A2之间要画一个箭头,A2与A4之间要画一个箭头, A1与A3之间是并列的关系,要画一个横向的箭头。

请问上面的需求应该用什么技术实现?
 

------解决方案--------------------
vml 标签可以 不过是ie上的
------解决方案--------------------
js 坐标
------解决方案--------------------
Java code
import javax.swing.*;
import java.awt.*;<p>/**
 * 在两个Swing控件之间画箭头
 * @author <a:href = "mailto:seth_yang@21cn.com">seth yang</a>
 */
public class Arrow {
    /** 源控件,即箭头的出发控件 */
    private JComponent source;
    /** 目标控件,即箭头的指向控件 */
    private JComponent target;
    /** 箭头中间的文本,通常是该箭头标识的关系的名称 */
    private String name = "";
    /** 源控件关联出去的字段 */
    private String sourceField = "";
    /** 目标控件的关联字段 */
    private String targetField = "";
    /** 箭头扇形的开始角度 */
    private int startAngle = 0;<p>    /** 箭头扇形的半径 */
    private static final int ARROW_HEIGHT = 20;
    /** 箭头扇形的角度 */
    private static final int ARROW_ANGLE = 30;<p>    public Arrow (JComponent source, JComponent target) {
        this (source.getName () + "_" + target.getName (), source, target);
    }
    /**
     * 构造函数
     *
     * 创建指定名称,源控件和目标控件的箭头
     * @param name 箭头的名称
     * @param source 箭头的出发控件
     * @param target 箭头的指向控件
     */
    public Arrow (String name, JComponent source, JComponent target) {
        this (name, source, target, source.getName (), target.getName ());
    }<p>    /**
     * 构造函数
     *
     * 创建指定名称,源控件和目标控件的箭头
     * @param name 箭头的名称
     * @param source 箭头的出发控件
     * @param target 箭头的指向控件
     * @param sourceField 箭头的出发字段
     * @param targetField 箭头的指向字段
     */
    public Arrow (String name, JComponent source, JComponent target, String sourceField, String targetField) {
        setName (name);
        setSource (source);
        setTarget (target);
        this.setSourceField (sourceField);
        this.setTargetField (targetField);
    }<p>    private Point getCenter (JComponent c) {
        int x = c.getLocation ().x;
        int y = c.getLocation ().y;
        int w = c.getSize ().width;
        int h = c.getSize ().height;<p>        return new Point (x + w / 2, y + h / 2);
    }<p>    public void draw (Graphics g) {
        g.setColor (Color.black);
        Point ps = getClosestPoint (getTarget (), getSource ());
        Point pt = getClosestPoint (getSource (), getTarget ());
        // 画线

        g.drawLine (ps.x, ps.y, pt.x, pt.y);<p>        // 画箭头

        // 简单起见,在这里从线段终点填充一个30度的扇形

        if (ps.x != pt.x && ps.y != pt.y) {
            double k = getK (ps, pt);
            if (ps.x > pt.x)
                startAngle = 360 - (int) (Math.atan (k) * 180 / Math.PI) - 15;
            else
                startAngle = 180 - (int) (Math.atan (k) * 180 / Math.PI) - 15;
        }
        // 圆心

        Point pc = new Point (pt.x - ARROW_HEIGHT, pt.y - ARROW_HEIGHT);
        g.fillArc (pc.x, pc.y, 2 * ARROW_HEIGHT, 2 * ARROW_HEIGHT, startAngle, ARROW_ANGLE);<p>        FontMetrics fm = g.getFontMetrics ();
        int ascent = fm.getAscent ();
        int descent = fm.getDescent ();<p>        // 在线条中心点处显示名称

        int mx = (ps.x + pt.x) / 2;
        int my = (ps.y + pt.y) / 2;
        g.drawString (name, mx, my + ascent);<p>        if (sourceField == null) sourceField = "";
        if (targetField == null) targetField = "";<p>        if (ps.y < pt.y) {// 源在目标上方,目标文字应该在更上面一些,源文字应该更下面一些

            // 在箭头处显示目标

            if (ps.x > pt.x) // 目标在源的左方

                g.drawString (getTargetField (), pt.x - fm.stringWidth (getTargetField ()),  pt.