d3js 实现水球图

在这里插入图片描述

d3js 源码地址:: http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6

官方提供的代码不能直接用,版本3.x 这是调整后v5能使用的。

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>7</title>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <link rel="stylesheet" type="text/css" href="/css.css" />
</head>

<body>
  <svg id="svg" width="300" height="300" onclick="javascript:gauge.update(NewValue())"></svg>
  <span>点击SVG更新数据</span>
 </body>
<script type='text/javascript'>

  var gauge = loadLiquidFillGauge("svg", 55, {
   
   
    circleColor: "#FF7777",
    textColor: "#FF4444",
    waveTextColor: "#FFAAAA",
    waveColor: "#FFDDDD",
    circleThickness: 0.02,
    circleFillGap: 0,
    textVertPosition: 0.2,
    waveAnimateTime: 1000,
    waveRiseTime: 3000
  });

  function NewValue() {
   
   
    if (Math.random() > .5) {
   
   
      return Math.round(Math.random() * 100);
    }
    return (Math.random() * 100).toFixed(1);
  }

  function loadLiquidFillGauge(elementId, value, config) {
   
   

    config = Object.assign({
   
   }, {
   
   
      minValue: 0, // 量规最小值.
      maxValue: 100, // 量规最大值.
      circleThickness: 0.05, // 外圆的厚度与半径的百分比.
      circleFillGap: 0.05, // 外圆与波圆之间的间隙大小与外圆半径的百分比.
      circleColor: "#178BCA", // 外圆的颜色.
      waveHeight: 0.05, // 波高与波圆半径的百分比.
      waveCount: 2, // 每波圈宽度的全波数.
      waveRiseTime: 1000, // 波从0上升到最终高度所需的时间,以毫秒为单位.
      waveAnimateTime: 18000, //  一个完整的波进入波圈的时间(以毫秒为单位).
      waveRise: true, // 控制波浪是否应该从0上升到它的全部高度,或从它的全部高度开始
      waveHeightScaling: true, // 控制波大小缩放在低和高填充百分比。当真值时,波高在50%填充时达到最大值,在0%和100%填充时达到最小值。这有助于防止波使波圈出现完全满或空时,接近它的最小或最大填充。
      waveAnimate: true, // 控制波形是滚动还是静态.
      waveColor: "#178BCA", // 填充波的颜色。
      waveOffset: 0, // 最初抵消波的量。0 = 无偏移。1 = 一个完整波的偏移量
      textVertPosition: .5, // 在波圈内显示百分比文本的高度。0 =下,1 =上.
      textSize: 1, // 要在波圈中显示的文本的相对高度。1 = 50%
      valueCountUp: true, // 如果为真,则显示的值从0计数到加载时的最终值。如果为false,则显示最终值。
      displayPercent: true, // 如果为真,值后面会显示%符号。
      textColor: "#045681", // 当波浪不重叠值文本时的颜色。
      waveTextColor: "#A4DBf8" // 当波浪与值文本重叠时的颜色.
    }, config);

    var gauge = d3.select("#" + elementId);
    var radius = Math.min(parseInt(gauge.style("width")), parseInt(gauge.style("height"))) / 2;
    var locationX = parseInt(gauge.style("width")) / 2 - radius;
    var locationY = parseInt(gauge.style("height")) / 2 - radius;
    var fillPercent = Math.max(config.minValue, Math.min(config.maxValue, value)) / config.maxValue;

    var waveHeightScale;
    if (config.waveHeightScaling) {
   
   
      waveHeightScale = d3.scaleLinear().range([0, config.waveHeight, 0]).domain([0, 50, 100]);
    } else {
   
   
      waveHeightScale = d3.scaleLinear().range([config.waveHeight, config.waveHeight]).domain([0, 100]);
    }

    var textPixels = (config.textSize * radius / 2);
    var textFinalValue = parseFloat(value).toFixed(2);
    var textStartValue = config.valueCountUp ? config.minValue : textFinalValue;
    var percentText = config.displayPercent ? "%" : "";
    var circleThickness = config.circleThickness * radius;
    var circleFillGap = config.circleFillGap * radius;
    var fillCircleMargin = circleThickness + circleFillGap;
    var fillCircleRadius = radius - fillCircleMargin;
    var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);

    var waveLength = fillCircleRadius * 2 / config.waveCount;
    var waveClipCount = 1 + config.waveCount;
    var waveClipWidth = waveLength * waveClipCount;

    // 四舍五入函数,以便在数值累计时始终显示正确的小数点后位数。
    var textRounder = (value) => Math.round(value);

    if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {
   
   
      textRounder = (value) => parseFloat(value).toFixed(1);
    }
    if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {
   
   
      textRounder = (value) => parseFloat(value).toFixed(2);
    }

    // 建立clip wave区域的数据。
    var data = Array.from({
   
    length: 41 * waveClipCount }, (_, i) => ({
   
    x: i / (40 * waveClipCount), y: (i / (40)) }));

    // 绘制外圆的比例。
    var gaugeCircleX = d3.scaleLinear().range([0, 2 * Math.PI]).domain([0, 1]);
    var gaugeCircleY = d3.scaleLinear().range([0, radius]).domain([0, radius]);

    // 用于控制剪切路径大小的尺度。
    var waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);
    var waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);

    // 用于控制裁剪路径位置的刻度。
    var waveRiseScale = d3.scaleLinear()
      // 剪辑区域的大小是填充圆的高度+波的高度,所以我们定位剪辑波这样,它将重叠填充圆在所有0%时,并将完全覆盖填充圆在100%。
      .range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)]).domain([0, 1]);

    var waveAnimateScale = d3.scaleLinear()
      .range([0, waveClipWidth - fillCircleRadius * 2]) // 将夹子区域推一个完整的波,然后弹回来。
      .domain([0, 1]);

    // 用于控制文本在量规内的位置的刻度。
    var textRiseScaleY = d3.scaleLinear()
      .range([fillCircleMargin + fillCircleRadius * 2, (fillCircleMargin + textPixels * 0.7)])
      .domain([0, 1]);

    // 在父SVG中居中测量。
    var gaugeGroup = gauge.append("g").attr('transform', `
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值