javascript - 流图 : two questions

标签 javascript graph charts d3.js stream-graph

我一直在玩 D3.js,我正在尝试使用实时数据制作流图可视化。

我确实研究了这篇文章 http://bost.ocks.org/mike/path/

我也看了这个问答 Svg clip-path within rectangle does not work 但这是一条线。我有一个 d3.svg.area 对象

然后我看了这篇文章 D3 Real-Time streamgraph (Graph Data Visualization) 却始终找不到答案

我的两个问题:

  • 绘制流图时,我注意到图表总是设置在底部。每次刷新计算函数都会找到数据的最大值,并将图形的底部设置在您绘制图形的元素的底部。

    var area = d3.svg.area()
       .x(function(data) { return data.x * width / Xmaximum; })
       .y0(function(data) { return height - data.y0 * height / Ymaximum; })
       .y1(function(data) { return height - (data.y + data.y0) * height / Ymaximum; });
    

如何让图形位于轴的中间? 我想我必须玩弄区域的 x、y0 和 y1,但究竟如何?

  • 如果您尝试我的代码,图表的一部分显示在左侧。 我知道有问题:

    vis.append("defs").append("clipPath")
       .attr("id", "clip")
      .append("rect")
       .attr("width", width)
       .attr("height", height);
    
     vis.append("g")
       .attr("clip-path", "url(#clip)");
    

我在其他主题和整个网络中搜索任何回复,但我一直被困在这里!

这是我的代码:

<!DOCTYPE html>
<html>
<head>
    <title>Test visu</title>
    <style>
        .line {
            fill: none;
            stroke: #000;
            stroke-width: 1.5px;
        }
        .axis path, .axis line {
            margin-left: 30px;
            fill: none;
            stroke: #000;
            shape-rendering: crispEdges;
        }
        svg {
            font: 10px sans-serif;
        }

        #restart{
            visibility: hidden;
        }

        #visu{
            margin-left: 70px;
            //border: 5px solid black;
            width: 900px;
            height: 500px;
        }

    </style>
</head>

<body>
    <div id="visu">
        <script src="http://mbostock.github.com/d3/d3.js?2.7.2"></script>
            var CONS = 100;

            var layers_number = 4;
            var samples_number = 50;

            var margin = {top: 6, right: 0, bottom: 6, left: 40};
            var width = 900 - margin.right;
            var height = 500 - margin.top - margin.bottom;

            var Xmaximum = samples_number - 1;
            var Ymaximum = CONS * layers_number;

            var initial_table = new Array();

            for (var i = 0 ; i < layers_number ; ++i){
                initial_table[i] = new Array();
                for (var j = 0 ; j < samples_number ; ++j){
                    initial_table[i][j] = randomNber();
                }
            }

            var values = new Array();
            for (var i = 0 ; i < layers_number ; ++i)
                values[i] = new Array();

            var data0 = d3.layout.stack().offset("wiggle")(init_layers(layers_number,samples_number));

            function color (indice){
                if (indice == 0)
                    return "green";
                else if (indice == 1)
                    return "blue";
                else if (indice == 2)
                    return "red";
                else if (indice == 3)
                    return "black";
                return "black";
            }

            var y = d3.scale.linear()
                              .domain([0, Ymaximum])
                              .range([height, 0]);

            var area = d3.svg.area()
                .x(function(data) { return data.x * width / Xmaximum; })
                .y0(function(data) { return height - data.y0 * height / Ymaximum; })
                .y1(function(data) { return height - (data.y + data.y0) * height / Ymaximum; });

            var vis = d3.select("div")
                .append("svg")
                  .style("margin-left", -margin.left + "px")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            vis.append("defs").append("clipPath")
                  .attr("id", "clip")
                .append("rect")
                  .attr("width", width)
                  .attr("height", height);

            vis.append("g")
                .attr("clip-path", "url(#clip)");

            vis.selectAll("path")
                .data(data0)
                .enter()
                .append("path")
                .style("fill", function(data, indice) { return color(indice); })
                .attr("d", area);

            vis.append("g")
                .attr("class", "y axis")
                  .call(d3.svg.axis().scale(y).ticks(5).orient("left"));

            transition();

            function transition() {
                data0 = d3.layout.stack().offset("wiggle")(update_layers(layers_number,samples_number));

                vis.selectAll("path")
                    .data(data0)
                    .attr("d", area)
                    .attr("transform", null)
                    .transition()
                    .duration(860)
                    .ease("linear")
                    .attr("transform", "translate(" + -(width / samples_number) + ")")
                    .each("end", function (data,indice) {
                        if (indice==0) transition();
                    });

                for (var i = 0 ; i < values.length ; ++i)
                    values[i].shift();
            }

            function init_layers(layers_number, samples_number) {
                return d3.range(layers_number).map(function(data,indice) {
                    for (var i = 0 ; i < samples_number ; i++)
                        values[indice][i] = initial_table[indice][i];
                    return values[indice].map(stream_index);
                });
            }

            function update_layers(layers_number, samples_number) {
                return d3.range(layers_number).map(function(data,indice) {
                    values[indice][samples_number] = randomNber();
                    return values[indice].map(stream_index);
                });
            }

            function stream_index(data, indice) {
                return {x: indice, y: Math.max(0, data)};
            }

            function randomNber(){
                return parseInt(Math.random()*100)+1;
            }   

    </div>
</body>
</html>

最佳答案

关于流居中的问题——使用堆栈布局的偏移特性:

https://github.com/mbostock/d3/wiki/Stack-Layout#wiki-offset

关于javascript - 流图 : two questions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10657838/

相关文章:

javascript - Google 图表 - 在 x 和 y 标签上拉伸(stretch)图表

javascript - 第一次使用 AJAX,通过 AJAX 进行 JSON 循环,数据分布在多个页面上?

javascript - 我正在导入和调用的功能未在 React 应用程序中运行

javascript - 为什么我的 sigma js 图表的工具提示不正确?

algorithm - 图实现 : why not use hashing?

wpf - 如何使用DynamicDataDisplay在wpf中的一个x-y平面中添加多个图形

javascript - 获取页面内容,就像用户打开一样

javascript - css flex 列自动高度

python - 如何在 matplotlib 中设置独立于刻度的条形宽度?

javascript - ChartJS,禁用多图数据上的一个图的工具提示