Javascript 如何使用enter()、exit()和“水平”更新;“堆叠”;图表

Javascript 如何使用enter()、exit()和“水平”更新;“堆叠”;图表,javascript,svg,d3.js,Javascript,Svg,D3.js,我有一个伪叠加的水平图。我之所以看到pseudo,是因为它模拟了一个堆叠图表,但实际上并不是多个堆叠值,而是3个不同的值,总计为100%。我不知道这种图表叫什么名字 不管怎么说,我正在试图弄清楚如何获取enter()和exit(),并在数据更改时更新图表。我以这个jsfiddle为例 svg结构开始时如下所示: <svg class="chart" width="756" height="50"> <g transform="translate(0,0)" width

我有一个伪叠加的水平图。我之所以看到pseudo,是因为它模拟了一个堆叠图表,但实际上并不是多个堆叠值,而是3个不同的值,总计为100%。我不知道这种图表叫什么名字

不管怎么说,我正在试图弄清楚如何获取
enter()
exit()
,并在数据更改时更新图表。我以这个jsfiddle为例

svg结构开始时如下所示:

<svg class="chart" width="756" height="50">
    <g transform="translate(0,0)" width="73.6">
        <rect height="50" width="224" style="fill: rgb(0, 0, 255);"></rect>
        <text x="113" y="25" dy=".35em">30%</text>
    </g>
    <g transform="translate(75,0)" width="451">
        <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
        <text x="226" y="25" dy=".35em">60%</text>
    </g>
    <g transform="translate(529.2000122070312,0)" width="224.8">
        <rect height="50" width="73" style="fill: rgb(128, 0, 128);"></rect>
        <text x="37" y="25" dy=".35em">10%</text>
    </g>
</svg>
<svg class="chart" width="756" height="50">
    <g transform="translate(0,0)" width="73.6">
        <rect height="50" width="224" style="fill: rgb(0, 0, 255);"></rect>
        <text x="113" y="25" dy=".35em">30%</text>
        <rect height="50" width="73" style="fill: rgb(0, 0, 255);"></rect>
        <text x="37" y="25" dy=".35em">10%</text>
    </g>
    <g transform="translate(75,0)" width="451">
        <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
        <text x="226" y="25" dy=".35em">60%</text>
        <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
        <text x="226" y="25" dy=".35em">60%</text>
    </g>
    <g transform="translate(529,0)" width="224.8">
        <rect height="50" width="73" style="fill: rgb(128, 0, 128);"></rect>
        <text x="37" y="25" dy=".35em">10%</text>
        <rect height="50" width="224" style="fill: rgb(128, 0, 128);"></rect>
        <text x="113" y="25" dy=".35em">30%</text>
    </g>
</svg>
 var barEnter = bar.enter().append('g');
 barEnter.append("rect");
 barEnter.append("text");

30%
60%
10%
在数据更改之后,看起来是这样的:

<svg class="chart" width="756" height="50">
    <g transform="translate(0,0)" width="73.6">
        <rect height="50" width="224" style="fill: rgb(0, 0, 255);"></rect>
        <text x="113" y="25" dy=".35em">30%</text>
    </g>
    <g transform="translate(75,0)" width="451">
        <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
        <text x="226" y="25" dy=".35em">60%</text>
    </g>
    <g transform="translate(529.2000122070312,0)" width="224.8">
        <rect height="50" width="73" style="fill: rgb(128, 0, 128);"></rect>
        <text x="37" y="25" dy=".35em">10%</text>
    </g>
</svg>
<svg class="chart" width="756" height="50">
    <g transform="translate(0,0)" width="73.6">
        <rect height="50" width="224" style="fill: rgb(0, 0, 255);"></rect>
        <text x="113" y="25" dy=".35em">30%</text>
        <rect height="50" width="73" style="fill: rgb(0, 0, 255);"></rect>
        <text x="37" y="25" dy=".35em">10%</text>
    </g>
    <g transform="translate(75,0)" width="451">
        <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
        <text x="226" y="25" dy=".35em">60%</text>
        <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
        <text x="226" y="25" dy=".35em">60%</text>
    </g>
    <g transform="translate(529,0)" width="224.8">
        <rect height="50" width="73" style="fill: rgb(128, 0, 128);"></rect>
        <text x="37" y="25" dy=".35em">10%</text>
        <rect height="50" width="224" style="fill: rgb(128, 0, 128);"></rect>
        <text x="113" y="25" dy=".35em">30%</text>
    </g>
</svg>
 var barEnter = bar.enter().append('g');
 barEnter.append("rect");
 barEnter.append("text");

30%
10%
60%
60%
10%
30%
矩形
文本
正在重新创建,旧的文本不会被删除。这里有两个问题:

  • 由于某种原因,
    rect
    s被复制。我不知道为什么
    exit()
    对他们不起作用

  • 正在复制
    文本
    s,因为此时已注释掉
    text.exit().remove()
    ,但由于某些原因取消注释会导致错误


  • 当您创建图表并随后更新其数据时,使用enter、update和exit功能的正确方法是什么?我一直在关注许多在线示例,并认为我使用了正确的语法,但显然它不能正常工作。

    您看到的问题的根源是您的
    文本和
    rect
    元素被分组在
    g
    元素中。您只需要处理
    g
    元素的输入、更新和退出选择。其他一切都与此无关。这意味着您需要保存
    g
    元素的enter选择,然后将其他元素附加到该元素

    结构如下所示:

    <svg class="chart" width="756" height="50">
        <g transform="translate(0,0)" width="73.6">
            <rect height="50" width="224" style="fill: rgb(0, 0, 255);"></rect>
            <text x="113" y="25" dy=".35em">30%</text>
        </g>
        <g transform="translate(75,0)" width="451">
            <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
            <text x="226" y="25" dy=".35em">60%</text>
        </g>
        <g transform="translate(529.2000122070312,0)" width="224.8">
            <rect height="50" width="73" style="fill: rgb(128, 0, 128);"></rect>
            <text x="37" y="25" dy=".35em">10%</text>
        </g>
    </svg>
    
    <svg class="chart" width="756" height="50">
        <g transform="translate(0,0)" width="73.6">
            <rect height="50" width="224" style="fill: rgb(0, 0, 255);"></rect>
            <text x="113" y="25" dy=".35em">30%</text>
            <rect height="50" width="73" style="fill: rgb(0, 0, 255);"></rect>
            <text x="37" y="25" dy=".35em">10%</text>
        </g>
        <g transform="translate(75,0)" width="451">
            <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
            <text x="226" y="25" dy=".35em">60%</text>
            <rect height="50" width="451" style="fill: rgb(255, 0, 0);"></rect>
            <text x="226" y="25" dy=".35em">60%</text>
        </g>
        <g transform="translate(529,0)" width="224.8">
            <rect height="50" width="73" style="fill: rgb(128, 0, 128);"></rect>
            <text x="37" y="25" dy=".35em">10%</text>
            <rect height="50" width="224" style="fill: rgb(128, 0, 128);"></rect>
            <text x="113" y="25" dy=".35em">30%</text>
        </g>
    </svg>
    
     var barEnter = bar.enter().append('g');
     barEnter.append("rect");
     barEnter.append("text");
    
    对于更新选择:

     bar.transition()...
     bar.select("rect").transition()...
     bar.select("text").transition()...
    
    对于退出选择,您只需要删除
    g
    元素,因为这也将删除其中包含的所有内容:

     bar.exit().remove();
    

    完成演示。

    +1关闭
    svg:g
    的输入/更新/退出选项会让很多人感到困惑。我想这是为了在我的脑海里巩固它…所以,我把它传递给这里的其他人。回过头来看,我可能应该强调键入数据的重要性。你的两种解释都非常有用。我想出来了。顺便说一下,在更新时执行transition()而不是在
    enter()
    上执行transition()的唯一方法是在两个位置使用相同的方法吗(如上面更新的JSFIDLE中所示)?我对
    g
    宽度和平移以及
    文本
    位置所做的计算在两个位置使用。一个在
    enter()
    处,然后再使用转换。这是实现它的唯一方法吗?不,输入选择实际上将附加元素合并到更新选择中。因此,从技术上讲,您所要做的就是添加元素。所有属性都可以在更新选择中设置。但是如果在更新部分有一个
    transition()
    ,当我加载页面时,元素在最初移动到位置时会发生转换,我希望它们立即出现在它们的位置上,并且只在更新时数据发生更改时才进行转换。这有意义吗?