2

如何使用Plottable.js 制作如下图所示的基本散点图?

  • 我的 JSON 有问题吗?
  • 如何显示负刻度?
  • 你会做其他不同的事情吗?

样式无关紧要,默认的 Plottable.js 一个就可以了。

在此处输入图像描述

window.onload = function() {
  var coordinates = [
    {
      x:"-5", 
      y:"3"
    }, {
      x:"2", 
      y:"-1,5"
    }, {
      x:"5", 
      y:"2,5"
    }
  ];
  
  var xScale = new Plottable.Scale.Linear();
  var yScale = new Plottable.Scale.Linear();
  var colorScale = new Plottable.Scale.Color("10");

  var xAxis = new Plottable.Axis.Numeric(xScale, "bottom");
  var yAxis = new Plottable.Axis.Numeric(yScale, "left");

  var plot = new Plottable.Plot.Scatter(xScale, yScale)
                      .addDataset(coordinates)
                      .project("x", "", xScale)
                      .project("y", "", yScale)
                      .project("fill", "", colorScale);
  
  var chart = new Plottable.Component.Table([
      [yAxis, plot],
      [null,  xAxis]
  ]);

  chart.renderTo("#my_chart");
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
    <link rel="stylesheet" href="https://rawgit.com/palantir/plottable/develop/plottable.css">
  </head>
  <body>
    <svg width="100%" height="600" id="my_chart"></svg>
    <script src="https://rawgit.com/mbostock/d3/master/d3.min.js"></script>
    <script src="https://rawgit.com/palantir/plottable/develop/plottable.min.js"></script>
  </body>
</html>

4

2 回答 2

2

Mark 的想法是正确的——表格系统本身并不支持这种布局,因此您需要手动控制它们的布局方式。但是,使用 Plottable API 的一些晦涩难懂的部分,有一种更简洁且支持更好的方式来布置您想要的图表,它不存在轴稍微偏移的问题。

第一个变化是我们将完全停止使用表格布局引擎,因为它不能做我们想要的。相反,我们会将所有组件放在一个Component.Group. 组只是在同一空间中覆盖组件,而根本不尝试定位它们。

var chart = new Plottable.Component.Group([yAxis, xAxis, plot]);

然后我们将使用在基本(抽象)组件类上定义的对齐和偏移方法。我们将 y 轴的 x-alignment 设置为“center”,将 x 轴的 y-alignment 设置为“center”。这将使轴位于图表的中心。

var xAxis = new Plottable.Axis.Numeric(xScale, "bottom").yAlign("center"); var yAxis = new Plottable.Axis.Numeric(yScale, "left").xAlign("center");

在这一点上我们还没有完成,因为要真正使轴居中,我们需要将它们向后移动它们自身宽度的一半。只有在图表渲染时才计算宽度(严格来说,在computeLayout调用中,但那是一个内部细节),所以我们需要在图表渲染后设置一个偏移量:

chart.renderTo("#plottable"); xAxis.yOffset(xAxis.height()/2); yAxis.xOffset(-yAxis.width()/2);

你可以在这里看到最终结果(它是 Mark 的 plnkr 的一个分支)。请注意,现在轴在图表的中心对齐,因为中心点完全位于 0,0 上。

于 2015-03-30T19:34:08.183 回答
1

这是我刚刚放在一起的几个例子。第一个是d3做你所要求的直接方式。第二个是被黑了plottable.js。由于plottable.js我找不到将轴定位在他们的桌子系统之外的方法,我不得不求助于手动移动它们。他们使用的桌面系统旨在让开发人员不必手动定位东西。当然,这很好也很容易,直到您想控制放置东西的位置。

这是 hack,在你渲染你的绘图后:

  // move the axis...
  d3.select(".y-axis")
    .attr('transform',"translate(" + width / 2 + "," + 0 + ")");        
  d3.select(".x-axis")
    .attr("transform", "translate(" + 48 + "," + height / 2 + ")");

请注意,我没有删除 plottable 放入的左侧边距(上面的 48 个)。这也可能被黑客入侵,但在那一点上,无论如何,plottable 为您提供了什么......

需要注意的是,每个绘图的不同外观完全是通过 CSS 控制的。

完成 d3 散点图:

// D3 EXAMPLE
var margin = {
  top: 20,
  right: 20,
  bottom: 20,
  left: 20
},
  width = 500 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

var x = d3.scale.linear()
  .range([0, width]);

var y = d3.scale.linear()
  .range([height, 0]);

var xAxis = d3.svg.axis()
  .scale(x)
  .orient("bottom");

var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left");

var svg = d3.select("#d3").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

x.domain([-100, 100]);
y.domain([-100, 100]);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(" + 0 + "," + height / 2 + ")")
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + width / 2 + "," + 0 + ")")
  .call(yAxis)
  .append("text");

svg.selectAll(".dot")
  .data(data)
  .enter().append("circle")
  .attr("class", "dot")
  .attr("r", function(d) {
    return d.r;
  })
  .attr("cx", function(d) {
    return x(d.x);
  })
  .attr("cy", function(d) {
    return y(d.y);
  })
  .style("fill", function(d) {
    return d.c;
  });

在此处输入图像描述

Plottable.js:

  // PLOTTABLE.JS
  var xScale = new Plottable.Scale.Linear();
  var yScale = new Plottable.Scale.Linear();

  var xAxis = new Plottable.Axis.Numeric(xScale, "bottom");
  var yAxis = new Plottable.Axis.Numeric(yScale, "left");

  var plot = new Plottable.Plot.Scatter(xScale, yScale);
  plot.addDataset(data);

  function getXDataValue(d) {
    return d.x;
  }
  plot.project("x", getXDataValue, xScale);
  function getYDataValue(d) {
    return d.y;
  }
  plot.project("y", getYDataValue, yScale);
  function getRDataValue(d){
    return d.r;
  }
  plot.project("r", getRDataValue);
  function getFillValue(d){
    return d.c;
  }
  plot.project("fill", getFillValue);
  var chart = new Plottable.Component.Table([
                    [yAxis, plot],
                    [null,  xAxis]
                  ]);
  chart.renderTo("#plottable");

  d3.select(".y-axis")
    .attr('transform',"translate(" + width / 2 + "," + 0 + ")");

  d3.select(".x-axis")
    .attr("transform", "translate(" + 48 + "," + height / 2 + ")");

在此处输入图像描述

于 2015-03-25T13:29:55.790 回答