我在一页上获取多个同型图时遇到麻烦。我认为问题可能出在svg <use>元素.selectAll(“ use”)

时间:2018-12-30 21:13:42

标签: javascript d3.js svg graph

这里是http://bl.ocks.org/alansmithy/d832fc03f6e6a91e99f4的链接此代码使用jquery滑块控制txt值和填充图标的数量。我已经在输入值中进行了硬编码,但是我也希望能够在一页上具有多个Isotype图表。文本值正确,但是两个图表的填充值(填充的图标数量)相同。

var svgDoc=d3.select("body").append("svg").attr("viewBox","0 0 105 25");

svgDoc.append("defs")
.append("g")
.attr("id","iconCustom")
.append("path")
        .attr("d","M3.5,2H2.7C3,1.8,3.3,1.5,3.3,1.1c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1c0,0.4,0.2,0.7,0.6,0.9H1.1C0.7,2,0.4,2.3,0.4,2.6v1.9c0,0.3,0.3,0.6,0.6,0.6h0.2c0,0,0,0.1,0,0.1v1.9c0,0.3,0.2,0.6,0.3,0.6h1.3c0.2,0,0.3-0.3,0.3-0.6V5.3c0,0,0-0.1,0-0.1h0.2c0.3,0,0.6-0.3,0.6-0.6V2.6C4.1,2.3,3.8,2,3.5,2z");

svgDoc.append("rect").attr("width",105).attr("height",25);

var numCols = 25;
var numRows = 2;
var xPadding = 2;
var yPadding = 8;

var hBuffer = 8;
var wBuffer = 4;

var myIndex=d3.range(numCols*numRows);

svgDoc.append("text")
.attr("id","txtValue")
.attr("x",xPadding)
.attr("y",yPadding)
.attr("dy",-3)
.text("0");

svgDoc.append("g")
.attr("id","pictoLayer")
.selectAll("use")
.data(myIndex)
.enter()
.append("use")
    .attr("xlink:href","#iconCustom")
    .attr("id",function(d)    {
        return "icon"+d;
    })
    .attr("x",function(d) {
        var remainder=d % numCols;//calculates the x position (column number) using modulus
        return xPadding+(remainder*wBuffer);//apply the buffer and return value
    })
      .attr("y",function(d) {
        var whole=Math.floor(d/numCols)//calculates the y position (row number)
        return yPadding+(whole*hBuffer);//apply the buffer and return the value
    })
    .classed("iconPlain",true);

var data = { percent: 75 };

///绘制图表的功能:

function drawIsotype(dataObject) {
valueLit = dataObject.percent;
total = numCols * numRows;
valuePict = total * (dataObject.percent / 100);

  d3.select("#txtValue").text(valueLit + '%');
  d3.selectAll("use").attr("class", function (d, i) {
  if (d < valuePict ) {
      return "iconSelected";
  } else {
      return "iconPlain";
  }
  });
  }

drawIsotype(data);

///这是完整的图形。如果我使用不同的变量名创建另一个图形,则可以得到第二张图,但是图标填充不正确。

 var svgDoc2=d3.select("#svg2").append("svg").attr("viewBox","0 0 105 45");

svgDoc2.append("defs")
.append("g")
.attr("id","iconCustom")
.append("path")
        .attr("d","M3.5,2H2.7C3,1.8,3.3,1.5,3.3,1.1c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1c0,0.4,0.2,0.7,0.6,0.9H1.1C0.7,2,0.4,2.3,0.4,2.6v1.9c0,0.3,0.3,0.6,0.6,0.6h0.2c0,0,0,0.1,0,0.1v1.9c0,0.3,0.2,0.6,0.3,0.6h1.3c0.2,0,0.3-0.3,0.3-0.6V5.3c0,0,0-0.1,0-0.1h0.2c0.3,0,0.6-0.3,0.6-0.6V2.6C4.1,2.3,3.8,2,3.5,2z");

svgDoc2.append("rect").attr("width",105).attr("height",35);

var numCols2 = 25;
var numRows2 = 3;
var xPadding2 = 2;
var yPadding2 = 8;
var hBuffer2 = 8;
var wBuffer2 = 4;

var myIndex2=d3.range(numCols2*numRows2);

svgDoc2.append("text")
.attr("id","txtValue2")
.attr("x",xPadding2)
.attr("y",yPadding2)
.attr("dy",-3)
.text("0");

svgDoc2.append("g")
.attr("id","pictoLayer")
.selectAll("use")
.data(myIndex2)
.enter()
.append("use")
    .attr("xlink:href","#iconCustom")
    .attr("id",function(e)    {
        return "icon"+e;
    })
    .attr("x",function(e) {
        var remainder=e % numCols2;//calculates the x position (column number) using modulus
        return xPadding2+(remainder*wBuffer2);//apply the buffer and return value
    })
      .attr("y",function(e) {
        var whole=Math.floor(e/numCols2)//calculates the y position (row number)
        return yPadding2+(whole*hBuffer2);//apply the buffer and return the value
    })
    .classed("iconPlain2",true);

var data2 = { percent2: 55 };

function drawIsotype2(dataObject2) {
valueLit2 = dataObject2.percent2;
total2 = numCols2 * numRows2;
valuePict2 = total2 * (dataObject2.percent2 / 100);

    d3.select("#txtValue2").text(valueLit2 + '%');
d3.selectAll("use").attr("class", function (e, i) {
    if (e < valuePict2 ) {
        return "iconSelected2";
    } else {
        return "iconPlain2";
    }
});

}
drawIsotype2(data2);

1 个答案:

答案 0 :(得分:1)

这两个路径定义之间没有太大的视觉差异。

问题是它们具有相同的idid在HTML DOM中应该是唯一的。

.attr("id","iconCustom2")  // for defs

.attr("xlink:href","#iconCustom2")  // for use

将解决参考问题。

您需要在特定的svg中选择use标签。以下内容简化了类属性设置。您可以注释几行。

// .classed("iconPlain",true);
// .classed("iconPlain2",true);

svgDoc.selectAll("use").classed("selected", d => d < valuePict );

svgDoc2.selectAll("use").classed("selected", d => d < valuePict2 );

您需要稍微更改CSS

.selected {fill:steelblue;}