使用d3 hexbin修复标记颜色和轴缩放

时间:2018-03-25 23:25:49

标签: javascript d3.js

我认为这篇文章有很多内容,如果我能在2天之内解决这个问题,我可能会提供赏金,因为它是我真正想要的图表制作!我试图按照显示in this Washington Post article on baseball players的hexbin图表的方式制作一些内容。 (必须向下滚动一下)

我正在建造really good hexbin starter code here。我对JS和d3相当新,我在一些调整中苦苦挣扎,包括:

  • 重新缩放(轴,数据,我不确定)因此,即使Y值非常小(例如,在0到1的比例范围内),hexbins也占据了大部分容器。 / LI>
  • 目前,色标仅基于落入每个六边形位置的数据点的数量。但是,我想将六边形颜色更新为与点相关的一些附加数据列的函数(平均值)。

以下是我在上面分享的链接中的代码:



// A. Create the SVG container starter code
var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");


// B. Random data
  // change which randomX and randomY are used. 
  // my baseball graph wll have Y values in the range -1 to 1
  // create a 3rd value in the points vector, for using to compute color
var randomX = d3.randomNormal(60, 20),
    randomY = d3.randomNormal(height / 2, 80),
    // randomY = d3.randomNormal(0, 0.3),
    // randomX = d3.randomNormal(width / 2, 80),
    colorZ = d3.randomNormal(0.35, 0.1),
    points = d3.range(2000).map(function() { return [randomX(), randomY(), colorZ()]; });

// C. The scales
// color scale starter code
var color = d3.scaleSequential(d3.interpolateLab("white", "steelblue"))
    .domain([0, 20]);

// hexbin starter code
var hexbin = d3.hexbin()
  .radius(8)
  .extent([[0, 0], [width, height]]);

// X and Y scale starter code (my changes commented out - didnt work) 
var x = d3.scaleLinear()
    .domain([0, width])
    .range([0, width]);

var y = d3.scaleLinear()
    .domain([0, 60])
    .range([height, 0]);


// D. append everything to grpah starte code
g.append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);

g.append("g")
    .attr("class", "hexagon")
    .attr("clip-path", "url(#clip)")
  .selectAll("path")
  .data(hexbin(points))
  .enter().append("path")
    .attr("d", hexbin.hexagon())
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    .attr("fill", function(d) { return color(d.length); });

g.append("g")
    .attr("class", "axis axis--y")
    .call(d3.axisLeft(y).tickSizeOuter(-width));

g.append("g")
    .attr("class", "axis axis--x")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x).tickSizeOuter(-height));

.hexagon {
  stroke: #000;
  stroke-width: 0.5px;
}

<svg width="700" height="500"></svg>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://d3js.org/d3-hexbin.v0.2.min.js"></script>
&#13;
&#13;
&#13;

关于我上面提到的两个问题:

轴调整 - 无法解决此问题正在挣扎。我的实际Y数据将在(-1到1)范围内,并且可以通过更改注释来添加上述代码中包含此范围内数据的测试数据。我尝试在轴刻度上更改域和范围,但这并没有帮助。

基于第三个参数而非计数的颜色 - 我认为这很难,我不确定它是否可行,但我想知道。如果点数据看起来像这样:

points = [
  {"x": 2.5, "y": 4, "count": 1}
  {"x": 3.5, "y": 3, "count": 1}
  {"x": 2.7, "y": 2, "count": 1}
  {"x": 2.8, "y": 3, "count": 1}
  {"x": 3.5, "y": 4, "count": 1}
  {"x": 2.5, "y": 3, "count": 1}
  {"x": 4.5, "y": 4, "count": 1}
  {"x": 1.8, "y": 2, "count": 1}
  ...
]

然后基本上六角形颜色来自计数列的总和。相反,我想使用我自己的第三列,并将颜色基于分组到每个十六进制的坐标值中该列的平均值。

points = [
  {"x": 2.5, "y": 4, "value": 2}
  {"x": 3.5, "y": 3, "value": 3.5}
  {"x": 2.7, "y": 2, "value": 3}
  {"x": 2.8, "y": 3, "value": 9}
  {"x": 3.5, "y": 4, "value": 8}
  {"x": 2.5, "y": 3, "value": 6}
  {"x": 4.5, "y": 4, "value": 5.3}
  {"x": 1.8, "y": 2, "value": 7}
  ...
]

然后颜色将基于&#34;值&#34;的平均值。每个bin的列。

对此有任何帮助表示赞赏,我知道这是一个很长的帖子,但我今天对此有点挣扎,能够制作这些可视化对我有所帮助!

0 个答案:

没有答案