使用D3.js创建简单的折线图和条形图

上一篇文章中 ,我们学习了如何使用D3.js (用于创建数据驱动的文档的JavaScript库)来实现气泡图。 D3.js可帮助使用HTML,SVG和CSS可视化数据。 在本文中,我们将看到如何使用D3.js来实现折线图和条形图。 在继续之前,您应该下载D3.js并熟悉我之前的文章中的内容

创建折线图

首先,我们需要一些数据进行绘制。 我们将使用以下数据。

var lineData = [{
  x: 1,
  y: 5
}, {
  x: 20,
  y: 20
}, {
  x: 40,
  y: 10
}, {
  x: 60,
  y: 40
}, {
  x: 80,
  y: 5
}, {
  x: 100,
  y: 60
}];

我们还需要一个<svg>元素来绘制图形。

<svg id="visualisation" width="1000" height="500"></svg>

接下来,我们需要创建x和y轴,为此,我们需要声明一个域和范围。 域定义了图表上显示的最小值和最大值,而范围是我们将覆盖的SVG的数量。 两个轴都需要根据lineData的数据进行lineData ,这意味着我们必须相应地设置域和范围。 绘制轴的代码如下所示。

var vis = d3.select('#visualisation'),
    WIDTH = 1000,
    HEIGHT = 500,
    MARGINS = {
      top: 20,
      right: 20,
      bottom: 20,
      left: 50
    },
    xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(lineData, function(d) {
      return d.x;
    }), d3.max(lineData, function(d) {
      return d.x;
    })]),
    yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(lineData, function(d) {
      return d.y;
    }), d3.max(lineData, function(d) {
      return d.y;
    })]),
    xAxis = d3.svg.axis()
      .scale(xRange)
      .tickSize(5)
      .tickSubdivide(true),
    yAxis = d3.svg.axis()
      .scale(yRange)
      .tickSize(5)
      .orient('left')
      .tickSubdivide(true);

vis.append('svg:g')
  .attr('class', 'x axis')
  .attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')')
  .call(xAxis);

vis.append('svg:g')
  .attr('class', 'y axis')
  .attr('transform', 'translate(' + (MARGINS.left) + ',0)')
  .call(yAxis);

在此代码中,我们为图形定义了WIDTHHEIGHTMARGINSxRangeyRange变量代表相应轴的域。 我们根据左右边界设置轴的范围。

接下来,由于域是我们将在图形上显示的数据,因此我们需要从lineData获得最小值和最大值。 这是使用d3.max()d3.min()方法完成的。

接下来,我们根据xRangeyRange变量创建了轴。 对于两个轴,我们分别将X和Y轴的比例尺定义为xRangeyRange 。 然后,我们仅将两个轴都附加到SVG并应用了变换。 现在,如果我们看一下Y轴,则需要将其向左定向。 因此,我们向yAxis施加了左方向。 我们对两个轴都进行了变换,同时保留了定义的边距,以使轴不接触SVG边距。

这是上述代码的演示 ,显示了两个轴。

接下来,我们需要将xRangeyRange应用于坐标,以将它们转换为绘图空间并在绘图空间上绘制一条线。 我们将使用d3.svg.line()绘制折线图。 为此,我们需要创建一个线生成器函数,该函数从数据中返回x和y坐标以绘制线。 这就是我们定义行生成器函数的方式:

var lineFunc = d3.svg.line()
  .x(function(d) {
    return xRange(d.x);
  })
  .y(function(d) {
    return yRange(d.y);
  })
  .interpolate('linear');

interpolate('linear')调用告诉D3绘制直线。

接下来,我们需要将SVG路径的d属性设置为从line函数返回的坐标。 使用以下代码可完成此操作。

vis.append('svg:path')
  .attr('d', lineFunc(lineData))
  .attr('stroke', 'blue')
  .attr('stroke-width', 2)
  .attr('fill', 'none');

我们使用stroke设置了线条颜色。 线条的宽度是使用stroke-width定义的。 我们已将fill设置为none ,以免不填充图形边界。 这是使用linear插值的折线图演示 ,这是使用basis插值的线图演示

创建条形图

接下来,我们将看看创建条形图。 由于我们已经创建了轴,因此不需要重新发明轮子。 但是,我们将稍微修改现有代码。 首先,示例数据和用于创建图表坐标轴的代码:

function InitChart() {

  var barData = [{
    'x': 1,
    'y': 5
  }, {
    'x': 20,
    'y': 20
  }, {
    'x': 40,
    'y': 10
  }, {
    'x': 60,
    'y': 40
  }, {
    'x': 80,
    'y': 5
  }, {
    'x': 100,
    'y': 60
  }];

  var vis = d3.select('#visualisation'),
    WIDTH = 1000,
    HEIGHT = 500,
    MARGINS = {
      top: 20,
      right: 20,
      bottom: 20,
      left: 50
    },
    xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(barData, function(d) {
        return d.x;
      }),
      d3.max(barData, function (d) {
        return d.x;
      })
    ]),

    yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(barData, function(d) {
        return d.y;
      }),
      d3.max(barData, function (d) {
        return d.y;
      })
    ]),

    xAxis = d3.svg.axis()
      .scale(xRange)
      .tickSize(5)
      .tickSubdivide(true),

    yAxis = d3.svg.axis()
      .scale(yRange)
      .tickSize(5)
      .orient("left")
      .tickSubdivide(true);

  vis.append('svg:g')
    .attr('class', 'x axis')
    .attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')')
    .call(xAxis);

  vis.append('svg:g')
    .attr('class', 'y axis')
    .attr('transform', 'translate(' + (MARGINS.left) + ',0)')
    .call(yAxis);
}

InitChart();

这是先前代码的演示 。 如果您查看Y轴,则比例从5开始。 这个最小值来自我们的样本数据,其中5是最小Y值。 因此,我们需要将Y轴从0缩放。为此,我们需要在InitChart()函数中修改yRange的域,如下所示:

yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([0,
  d3.max(barData, function(d) {
    return d.y;
  })]);

对于条形图,我们将使用ordinal比例尺而不是linear比例尺。 序数标度有助于维护离散域。 有关更详细的信息,请参阅序数表上官方文档

我们还将使用rangeRoundBands在图表条上划分宽度。 我们会在修改xRange使用ordinal规模和rangeRoundBands ,如下图所示。 请注意,我们还将条形图之间的间距设置为0.1。

xRange = d3.scale.ordinal().rangeRoundBands([MARGINS.left, WIDTH - MARGINS.right], 0.1).domain(barData.map(function(d) {
  return d.x;
}));

接下来,我们需要为图表数据创建矩形条。 我们将使用x和y坐标设置矩形条的heightwidth ,将示例数据绑定到矩形。 代码如下:

vis.selectAll('rect')
  .data(barData)
  .enter()
  .append('rect')
  .attr('x', function(d) { // sets the x position of the bar
    return xRange(d.x);
  })
  .attr('y', function(d) { // sets the y position of the bar
    return yRange(d.y);
  })
  .attr('width', xRange.rangeBand()) // sets the width of bar
  .attr('height', function(d) {      // sets the height of bar
    return ((HEIGHT - MARGINS.bottom) - yRange(d.y));
  })
  .attr('fill', 'grey');   // fills the bar with grey color

这是运行中的条形图的演示

添加活动

为了提高交互性,我们还可以将事件附加到栏上。 我们可以附加一个事件来突出显示mouseover的栏。 这是可以实现的方法:

vis.selectAll('rect')
  .data(barData)
  .enter()
  .append('rect')
  .attr('x', function(d) {
    return xRange(d.x);
  })
  .attr('y', function(d) {
    return yRange(d.y);
  })
  .attr('width', xRange.rangeBand())
  .attr('height', function(d) {
    return ((HEIGHT - MARGINS.bottom) - yRange(d.y));
  })
  .attr('fill', 'grey')
  .on('mouseover', function(d) {
    d3.select(this)
      .attr('fill', 'blue');
  });

在此代码中, on('mouseover')添加了一个事件处理程序,该事件处理程序在鼠标悬停时调用,这使悬停的条变为蓝色。 这是演示此效果的演示

您可能会注意到, mouseout ,这些条不会再次变为灰色。 让我们附加另一个事件,以在鼠标移出时将其恢复为先前的颜色。 更新后的代码如下所示:

vis.selectAll('rect')
  .data(barData)
  .enter()
  .append('rect')
  .attr('x', function(d) {
    return xRange(d.x);
  })
  .attr('y', function(d) {
    return yRange(d.y);
  })
  .attr('width', xRange.rangeBand())
  .attr('height', function(d) {
    return ((HEIGHT - MARGINS.bottom) - yRange(d.y));
  })
  .attr('fill', 'grey')
  .on('mouseover', function(d) {
    d3.select(this)
      .attr('fill', 'blue');
  })
  .on('mouseout', function(d) {
    d3.select(this)
      .attr('fill', 'grey');
  });

并且,这里是上述代码的演示示例

结论

D3.js是一个很棒的JavaScript库,用于数据可视化。 在本教程中,我们着重于创建相当简单的条形图和折线图。 如果您有兴趣进行更多实验,请尝试从D3库向本文的图表中添加其他可视化技术。

From: https://www.sitepoint.com/creating-simple-line-bar-charts-using-d3-js/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值