如何在数据驱动文档中创建动态 json 并在 jsp 中获取 json 响应

How to make a dynamic json and get the json response in a jsp in data driven documents

本文关键字:json 并在 jsp 响应 获取 动态 创建 数据驱动 文档      更新时间:2023-09-26

我是D3 api的新手。我必须创建一个树状结构,它有一个 json 文件,其中的值是硬编码的,我有一个 servlet,我从数据库中获取一些值,在那里我必须在 servlet 中动态制作 json,并且必须将响应设置回 D3。这是我写d3的html。我能够使用 java 类创建 json,但不能从 D3 .js 调用它,这是我的 java 文件和创建的 json 以及我的 html 文件.....

public class Test {
public static void main(String[] args) 
{
    // hierarchical data in a flattened list
    String[][] data = {
            {"Toyota", "Gas", "Compact", "Corolla"},
            {"Toyota", "Gas", "Compact", "Camry"},
            {"Toyota", "Hybrid", "Compact", "Prius"},
            {"Honda", "Gas", "Compact", "Civic"}
    };
    TreeManager treeManager = new TreeManager();
    for(String[] row : data)
    {
        // build the path to our items in the tree
        List<String> path = new ArrayList<String>();
        for(String item : row)
        {
            // add this item to our path
            path.add(item);
            // will add it unless an Item with this name already exists at this path
            treeManager.addData(treeManager, path);
        }
    }
    treeManager.getData(data[0]).putValue("MPG", 38);
    treeManager.getData(data[1]).putValue("MPG", 28);
    Gson gson = new Gson();
    System.out.println(gson.toJson(treeManager));
}
/**
 * This base class provides the hierarchical property of
 * an object that contains a Map of child objects of the same type.
 * It also has a field - Name
 *
 */
public static abstract class TreeItem implements Iterable<TreeItem>{
    private Map<String, TreeItem> children;     
    private String name;
    public TreeItem() {
        children = new HashMap<String, TreeItem>();
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void addChild(String key, TreeItem data) 
    {           
        children.put(key, data);
    }
    public TreeItem getChild(String key) 
    {           
        return children.get(key);
    }
    public boolean hasChild(String key) 
    {           
        return children.containsKey(key);
    }
    @Override
    public Iterator<TreeItem> iterator() {          
        return children.values().iterator();
    }           
}
/**
 * This is our special case, root node. It is a TreeItem in itself
 * but contains methods for building and retrieving items from our tree
 *
 */
public static class TreeManager extends TreeItem
{       
    /**
     * Will add an Item to the tree at the specified path with the value
     * equal to the last item in the path, unless that Item already exists 
     */
    public void addData(List<String> path)
    {
        addData(this, path);
    }
    private void addData(TreeItem parent, List<String> path)
    {
        // if we're at the end of the path - create a node
        String data = path.get(0);
        if(path.size() == 1)
        {
            // unless there is already a node with this name
            if(!parent.hasChild(data))
            {
                Group group = new Group();
                group.setName(data);
                parent.addChild(data, group);
            }
        }
        else
        {
            // pass the tail of this path down to the next level in the hierarchy
            addData(parent.getChild(data), path.subList(1, path.size()));
        }
    }
    public Group getData(String[] path)
    {
        return (Group) getData(this, Arrays.asList(path));
    }
    public Group getData(List<String> path)
    {
        return (Group) getData(this, path);
    }
    private TreeItem getData(TreeItem parent, List<String> path)
    {
        if(parent == null || path.size() == 0)
        {
            throw new IllegalArgumentException("Invalid path specified in getData, remainder: " 
                    + Arrays.toString(path.toArray()));
        }
        String data = path.get(0);
        if(path.size() == 1)
        {
            return parent.getChild(data);
        }
        else
        {
            // pass the tail of this path down to the next level in the hierarchy
            return getData(parent.getChild(data), path.subList(1, path.size()));
        }
    }
}
public static class Group extends TreeItem {
    private Map<String, Object> properties;
    public Object getValue(Object key) {
        return properties.get(key);
    }
    public Object putValue(String key, Object value) {
        return properties.put(key, value);
    }
    public Group () {
        super();
        properties = new HashMap<String, Object>();
       }       
   }

}

这是我们的 JSON

   {
"children": {
    "Toyota": {
        "properties": {},
        "children": {
            "Hybrid": {
                "properties": {},
                "children": {
                    "Compact": {
                        "properties": {},
                        "children": {
                            "Prius": {
                                "properties": {},
                                "children": {},
                                "name": "Prius"
                            }
                        },
                        "name": "Compact"
                    }
                },
                "name": "Hybrid"
            },
            "Gas": {
                "properties": {},
                "children": {
                    "Compact": {
                        "properties": {},
                        "children": {
                            "Corolla": {
                                "properties": {
                                    "MPG": 38
                                },
                                "children": {},
                                "name": "Corolla"
                            },
                            "Camry": {
                                "properties": {
                                    "MPG": 28
                                },
                                "children": {},
                                "name": "Camry"
                            }
                        },
                        "name": "Compact"
                    }
                },
                "name": "Gas"
            }
        },
        "name": "Toyota"
    },
    "Honda": {
        "properties": {},
        "children": {
            "Gas": {
                "properties": {},
                "children": {
                    "Compact": {
                        "properties": {},
                        "children": {
                            "Civic": {
                                "properties": {},
                                "children": {},
                                "name": "Civic"
                            }
                        },
                        "name": "Compact"
                    }
                },
                "name": "Gas"
            }
        },
        "name": "Honda"
           }
         }
     }

这是我的 html 文件...

<meta charset="utf-8">

.node circle {
    cursor: pointer;
    stroke: #3182bd;
    stroke-width: 1.5px;
}
.node text {
    font: 10px sans-serif;
    pointer-events: none;
    text-anchor: middle;
}
line.link {
    fill: none;
    stroke: #9ecae1;
    stroke-width: 1.5px;
}

<script type="text/javascript" src="d3/d3.v3.min.js"></script>
<script>
    var width = 960,
    height = 500,
    root;
    var force = d3.layout.force()
    .linkDistance(80)
    .charge(-120)
    .gravity(.04)
    .size([width, height])
    .on("tick", tick);
    //adding as svg element
    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
    var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");
d3.json("graph.json", function(error, json) {
        root = json;
        update(); //responsible for creating the layout
    });
    function update() {
        var nodes = flatten(root),
        /*
         *d3.layout.tree() is the starting point 
         *for tree layouts in D3. 
         *The call to this function returns an object
         * that contains a bunch of methods to configure 
         * the layout and also provides methods to 
         * compute the layout
         **/           
        links = d3.layout.tree().links(nodes);//attach the nodes
        // Restart the force layout.
        force
        .nodes(nodes)
        .links(links)
        .start();
        // Update links.
        link = link.data(links, function(d) { return d.target.id; });
        link.exit().remove();
        link.enter().insert("line", ".node")
        .attr("class", "link");
        // Update nodes.
        node = node.data(nodes, function(d) { return d.id; });
        node.exit().remove();
        var nodeEnter = node.enter().append("g")
        .attr("class", "node")
        .on("click", click)
        .call(force.drag);
        nodeEnter.append("circle")
        .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; });
        nodeEnter.append("text")
        .attr("dy", ".35em")
        .text(function(d) { return d.name; });
        node.select("circle")
        .style("fill", color);
    }

    /*Giving elements on click*/
    function tick() {
        link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });
        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    }

    /*Adjusting the color of each node*/
    function color(d) {
        return d._children ? "#3182bd" // collapsed package
        : d.children ? "#c6dbef" // expanded package
        : "#fd8d3c"; // leaf node
    }
    // Toggle children on click.
    function click(d) {
        if (d3.event.defaultPrevented) return; // ignore drag
        if (d.children) {
            d._children = d.children;
            d.children = null;
        } else {
            d.children = d._children;
            d._children = null;
        }
        update();
    }
    // Returns a list of all nodes under the root.
    function flatten(root) {
        var nodes = [], i = 0;
        function recurse(node) {
            if (node.children) node.children.forEach(recurse);
            if (!node.id) node.id = ++i;
            nodes.push(node);
        }
        recurse(root);
        return nodes;
    }
</script>

这是 JSON 和 HTML 文件,现在我必须动态制作 json 并设置响应到 D3 接口。任何人请帮忙...

此代码使用 AJAX 请求从服务器检索 JSON 文件:

d3.json("graph.json", function(error, json) {
    root = json;
    update(); //responsible for creating the layout
});

现在,您使用的URL将简单地从与服务器上的HTML文件相同的位置获取一个名为"graph.json"的静态文件。 您可以将此 URL 更改为在 servlet 中调用doGet的 URL,然后doGet返回所需的动态 JSON。