用高度百分比(d3.js)填写以象形图绘制的最后svg图形

时间:2016-06-20 14:37:11

标签: javascript d3.js svg

我正在尝试修改此pictogram。我想创建一个类似的影响,但没有用户输入。我的目标是显示50个SVG图形,但是使用100个数据。例如,如果数据输入为27,则将填充13.5个图形。

根据我在d3工作的有限经验,我知道代码将不得不省略大多数(如果不是全部)css。这是我迄今为止的尝试;

http://plnkr.co/edit/tZXJ0ZqHp2y3PqYPunah?p=preview

我不确定如何处理最后一个元素的转换,以便根据27/2的数据,它只会将最后一个图形填充50%?

这是代码;

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

//define an icon store it in svg <defs> elements as a reusable component - this geometry can be generated from Inkscape, Illustrator or similar
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");


//specify the number of columns and rows for pictogram layout
var numCols = 10;
var numRows = 5;

//padding for the grid
var xPadding = 10;
var yPadding = 15;

//horizontal and vertical spacing between the icons
var hBuffer = 9;
var wBuffer = 8;

//generate a d3 range for the total number of required elements
var myIndex = d3.range(numCols * numRows);
var myData = 27/2

//create group element and create an svg <use> element for each icon
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
  })
  .transition()
  .duration(1000)
  .style("fill", function(d) {
    if(d < myData) {
      return "steelblue"
    }

  })

作为脚注;

我也在尝试按照输入,更新,退出范例进行操作,这样我就可以轻松地使用新数据进行更新,虽然它不是问题的基础,但有关如何使用该数据编写代码的任何建议心中也非常感激!

First attempt,如果您认为继续这种方式可以更好地解决问题)

提前感谢任何建议/帮助!

1 个答案:

答案 0 :(得分:3)

最简单的解决方案可能是使用渐变来实现“半人”的情况,然后使用类将渐变附加到您的实例,就像您对黑色和蓝色变体所做的那样。

.half
{
  fill: url(#halfgrad);
}
<svg viewBox="0 0 100 100">
  <defs>
    <linearGradient id="halfgrad">
      <stop offset="0.5" stop-color="steelblue"/>
      <stop offset="0.5" stop-color="black"/>
    </linearGradient>
  </defs>

  <path 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" class="half"/>
</svg>

我让梯度水平分裂了男人。但是如果你想要它垂直分割而只是将linearGradient改为:

<linearGradient id="halfgrad" x2="0" y2="1">