将坐标转换为 CSS 以像素为单位的固定定位

Translating coordinates to CSS fixed positioning in pixels

所以我制作了一个 animated square pie chart,它使用一些基本的 CSS 以大网格格式显示自身。但是,如何更改每个单独的块(较大的正方形)以排列在州地图网格中?

我在 javascript 中有以下代码,我认为可以通过 CSS 重新组织它们,我知道我需要“将坐标转换为 CSS 固定定位以像素为单位”,但我不确定如何将两者联系起来。

<script id="field_details">
var field_details = {
  "ME" : { "state": "ME", "row": 0, "col": 10 },
  "WI" : { "state": "WI", "row": 1, "col": 5 },
  "VT" : { "state": "VT", "row": 1, "col": 9 },
  "NH" : { "state": "NH", "row": 1, "col": 10 },
  "WA" : { "state": "WA", "row": 2, "col": 0 },
  "ID" : { "state": "ID", "row": 2, "col": 1 },
  "MT" : { "state": "MT", "row": 2, "col": 2 },
  "ND" : { "state": "ND", "row": 2, "col": 3 },
...

我看到的问题是“field_details”已经在下面的代码中被调用。它接收数据集,根据状态数据创建一个 100 单位的小网格,并将其显示到 canvas.

d3.csv("data/test3.csv", type, function(error, data) {
if (error) throw error;

var valfields = d3.keys(field_details);

// Make data accessible by grp key
data.forEach(function(o) {
    grp_vals["grp" + o.agegrp] = o;
});


//
// Setup grid.
//
var cells = [];
d3.select("#grid").text().split("\n").forEach(function(line, i) {
  //replace every alphanumeric character with an empty string
  var re = /\w+/g, m;
  while (m = re.exec(line)) cells.push({
    name: m[0],
    selected: 1,
    x: m.index / 3,
    y: i
  });
});


//
// Make a square pie for each field.
//
valfields.forEach(function(v,i) {
    var grid_width = d3.max(cells, function(d) { return d.x; }) + 1,
        grid_height = d3.max(cells, function(d) { return d.y; }) + 1,
        cell_size = width / grid_width,
        holder_width = width + margin.left + margin.right;


    var div = d3.select("#charts").append("div")
        .attr("id", "holder"+v)
        .attr("class", "chartholder")
        div.append("h3").html(field_details[v].desc );

所有代码位于link,包括CSS。

感谢任何help/guidance!

更新 2

HTML

 </style>
 </head>
<div id="main-wrapper">
<h1 class="centered">Test</h1>
<p class="desc centered">Test</p>

<div id="update">
<div id="update">
        <div class="clr"></div>
    </div>
    <div id="agegrp" class="buttons">
        <h3>Test</h3>
        <div a href="#" data-toggle="tooltip" data-placement="bottom" 
         data-trigger="hover focus" title ="Test"
          class="button current test" data-val="1" id = "HE" name = "HE" 
          value = "HE">Test</div>

        <div a href="#" data-toggle="tooltip" data-placement="bottom" 
         data-trigger="hover focus" title ="Test"
          class="button 2 test" data-val="2" id = "GM" name = "GM" value = 
           "GM">Test</div>

            <div a href="#" data-toggle="tooltip" data-placement="bottom" 
              data-trigger="hover focus" title = "Test"
               class="button 3 test" data-val="3" id = "RC" name = "RC" 
                 value = "RC">Test</div>

        <div a href="#" data-toggle="tooltip" data-placement="bottom" 
           data-trigger="hover focus" title = "Test"
          class="button 4 test" data-val="4" style="margin-right:0" id = 
            "CAPS" name = "CAPS" value ="CAPS">Test</div>

        <div class="clr"></div>

<div id="map" style="position:absolute" class="block"></div>

    </div>


    <div id="racesimp" class="buttons">
    </div>
</div><!-- @end #update -->

  <div class="clr"></div>
  <div class="genericholder">

      <div  id="charts" style="position:relative"></div>
      <div id="grid2"></div>
  </div>
<div id="container">
</div>

Javascript

var valfields = d3.keys(field_details);
// Make data accessible by grp key
data.forEach(function(o) {
    grp_vals["grp" + o.agegrp] = o;
});

//
// Setup grid.
//
var cells = [];
d3.select("#grid").text().split("\n").forEach(function(line, i) {
  //replace every alphanumeric character with an empty string
  var re = /\w+/g, m;
  while (m = re.exec(line)) cells.push({
    name: m[0],
    selected: 1,
    x: m.index / 3,
    y: i
  });
});


//
// Make a square pie for each field.
//
valfields.forEach(function(v,i) {
    var grid_width = d3.max(cells, function(d) { return d.x; }) + 1,
        grid_height = d3.max(cells, function(d) { return d.y; }) + 1,
        cell_size = width / grid_width,
        holder_width = width + margin.left + margin.right;

    var div = d3.select("#charts").append("div")
        .attr("id", "holder"+v)
        .attr("class", "chartholder")
        div.style("top",(data.row * 35) + "px");
        div.style("left",(data.col * 35) + "px");
        div.append("h3").html(field_details[v].desc );

CSS

#charts {
  position: relative;
  margin-top: 20px;
  width: 100%;
}
#map {
  position: relative;
  width: 100%;
  height: 100%
}
  .div.css {
  position: absolute;
  width: 100%;
  height: 100%
}
  .newdiv {
  position: absolute;
  width: 100%;
  height: 100%
}
  .block {
  position: absolute;
  width: 100%;
  height: 100%
}

看起来您已经完成了将地理地图布局转换为行和列的困难部分;所以这就像将 'row' 和 'col' 值乘以块的宽度/高度一样简单,并将结果用作像素位置。

我将跳过你的代码中与问题无关的部分,并根据你的 'field_details' 对象将 "blocks" 绘制为单个元素:

var field_details = {
ME: {row: 0, col: 10}, WI: {row: 1, col: 5}, VT: {row: 1, col: 9}, NH: {row: 1, col: 10}, WA: {row: 2, col: 0}, ID: {row: 2, col: 1}, MT: {row: 2, col: 2}, ND: {row: 2, col: 3}, MN: {row: 2, col: 4}, IL: {row: 2, col: 5}, MI: {row: 2, col: 6}, NY: {row: 2, col: 8}, MA: {row: 2, col: 9}, OR: {row: 3, col: 0}, NV: {row: 3, col: 1}, WY: {row: 3, col: 2}, SD: {row: 3, col: 3}, IA: {row: 3, col: 4}, IN: {row: 3, col: 5}, OH: {row: 3, col: 6}, PA: {row: 3, col: 7}, NJ: {row: 3, col: 8}, CT: {row: 3, col: 9}, RI: {row: 3, col: 10}, CA: {row: 4, col: 0}, UT: {row: 4, col: 1}, CO: {row: 4, col: 2}, NE: {row: 4, col: 3}, MO: {row: 4, col: 4}, KY: {row: 4, col: 5}, WV: {row: 4, col: 6}, VA: {row: 4, col: 7}, MD: {row: 4, col: 8}, DE: {row: 4, col: 9}, AZ: {row: 5, col: 1}, NM: {row: 5, col: 2}, KS: {row: 5, col: 3}, AR: {row: 5, col: 4}, TN: {row: 5, col: 5}, NC: {row: 5, col: 6}, SC: {row: 5, col: 7}, OK: {row: 6, col: 3}, LA: {row: 6, col: 4}, MS: {row: 6, col: 5}, AL: {row: 6, col: 6}, GA: {row: 6, col: 7}, HI: {row: 7, col: 0}, AK: {row: 7, col: 1}, TX: {row: 7, col: 3}, FL: {row: 7, col: 8} 
};

for (state in field_details) {
  var data = field_details[state];

  // create the element (yours probably already exist, so just access them by ID instead)
  var newElement = $('<div class="block">'+state+'<div>');
  $('#map').append(newElement);

  // set the position (row times width, col times height plus a bit of padding).  I hardcoded the sizes here out of laziness.
  newElement.css("top",(data.row * 35) + "px"); 
  newElement.css("left",(data.col * 35) + "px");
}
#map {
  position: relative;
  width: 100%;
  height: 100%
}

.block {
  font-size: 10px;
  width: 30px;
  height: 30px;
  border: 1px solid #000;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="map">
</div>

(因为它使用绝对定位,所以不需要在严格的网格上;这只是您的 row/col 数据的结果。您可以通过稍微调整一些状态的定位来改进布局-- 例如,将数据中的所有 row/col 值加倍并乘以 width/height 的一半将使您将 FL 和 TX 向左或向右微调半步,或者东北部州 half-step南...)

更新

将此绑定到您现有的代码中:

您已经在遍历 field_details 并创建 DOM 元素,就像我在上面的示例中一样。所以你大部分时间都在那里;只需添加定位即可:

valfields.forEach(function(v,i) {
    // ...
    var div = d3.select("#charts").append("div")
    // ...

    // New code: position the elements:
    div.style("top",(/* math */) + "px"); 
    div.style("left",(/* math */) + "px");          
    // (make sure those divs get a `position:absolute`, and #charts or some other containing element has `position:relative`
    // ...
}

最后更新

这些确切的行,替换了您现有的 div.style 行,在您的代码中为我工作:

div.style("position", "absolute"); // or set this in CSS on .holder
div.style("top", field_details[v].row * 95 + "px");
div.style("left", field_details[v].col * 95 + "px");