首页 > 解决方案 > 如何将动态数据文本放在d3中的矩形内

问题描述

更新方法:提前致谢。我正在根据 api 响应数据创建矩形。当新数据从 api 返回时,矩形将被删除并重新创建。我想在矩形内添加文本实现相同的目的,这意味着一旦我收到新数据,文本就应该根据数据被覆盖或重新创建。

          /* update selection*/
      var rectangles = vis.ganttSvgRef.selectAll("rect").data(chartData);
         /*exit selection*/
       rectangles.exit().remove();
        /*enter selection*/
      var innerRects = rectangles.enter().append("rect").merge(rectangles)
    .attr("x", function (d) {
        return vis.timeScale(parseTime(d.arrivalTime_data)) + sidePadding;
    })
    .attr("y", function (d, i) {
        for (var j = 0; j < slotNumber.length; j++) {
            if (d.slot == slotNumber[j]) {
                return vis.yScale(d.slot);
            }
        }
    })
    .attr("width", function (d) {
        return (vis.timeScale(parseTime(d.departureTime_data)) - 
      vis.timeScale(parseTime(d.arrivalTime_data)));
    })
    .attr("height", barHeight)
    .attr("stroke", "none")
    .attr("fill", function (d) {
        for (var i = 0; i < vesselsNames.length; i++) {
            return serviceColorSelector[d.serviceName_data]
        }
    })

如何在中间的矩形中添加文本,这也应该根据接收到的数据进行更新。谢谢

@Michael Rovinsky 建议的更新代码:此代码非常适合在矩形内附加文本,但在少数矩形上,文本溢出矩形区域之外。如果它从矩形区域溢出,我不想显示文本,或者如果它从矩形区域溢出,我该如何隐藏文本?

 var rectangles = vis.ganttSvgRef.selectAll("rect")
        .data(chartData);
    rectangles.exit().remove();

    var innerRects = rectangles.enter().append("g");
    let rectinst = innerRects.append("rect").merge(rectangles)
        .attr("x", function (d) {
            return vis.timeScale(parseTime(d.arrivalTime_data)) + 
                   sidePadding;
        })
        .attr("y", function (d, i) {
            for (var j = 0; j < slotNumber.length; j++) {
                if (d.slot == slotNumber[j]) {
                    return vis.yScale(d.slot);
                }
            }
        })
        .attr("width", function (d) {
            return (vis.timeScale(parseTime(d.departureTime_data)) - 
        vis.timeScale(parseTime(d.arrivalTime_data)));
        })
        .attr("height", barHeight)
        .attr("stroke", "none")
        .attr("fill", function (d) {
            for (var i = 0; i < vesselsNames.length; i++) {
                return serviceColorSelector[d.serviceName_data]
            }
        })
    let text = vis.ganttSvgRef.selectAll(".rect-text")
        .data(chartData);
    text.exit().remove();
    innerRects.append("text").merge(text)
        .attr("class", 'rect-text')
        .text(function (d) {
            let rectWidth = (vis.timeScale(parseTime(d.departureTime_data)) - 
          vis.timeScale(parseTime(d.arrivalTime_data)));
            console.log("rect width : ", rectWidth)
            console.log("d.vesselName_data : ", 
        vis.timeScale(d.vesselName_data.length))
            return d.vesselName_data;
        })
        .attr("x", function (d) {
            return (vis.timeScale(parseTime(d.departureTime_data)) -  
         vis.timeScale(parseTime(d.arrivalTime_data))) / 2 + 
         vis.timeScale(parseTime(d.arrivalTime_data)) + sidePadding;
           })
        .attr("y", function (d, i) {
            for (var j = 0; j < slotNumber.length; j++) {
                if (d.slot == slotNumber[j]) {
                    return vis.yScale(d.slot) + (barHeight / 2);
                }
            }
        })
        .attr("font-size", barHeight / 2)
        .attr("text-anchor", "middle")
        .attr("text-height", barHeight)
        .attr("fill", '#fff');

标签: d3.js

解决方案


在enter ()上附加“ g ”而不是“ rect ” :

const containers = rectangles.enter().append("g");

在“ g ”下附加“ rect ”和“ text ”:

containers.append("rect").attr('width', ...).attr('height', ...)...

containers.append("text").text('My Text Here')...

推荐阅读