使用d3js画K线图

使用 必应谷歌 搜索了一圈,发现只有一篇使用d3js画K线图的文章,但是将相关的HTML和JavaScript代码内容保存为.html文件并在浏览器打开后,发现当使用d3js V4版本时并不能画出K线图来,原因是当使用d3js V4版本时,attr(parameter)方法不再支持以 JSON对象 作为参数设置对象属性。

以下是经过修改并能正确运行的代码:

<!DOCTYPE html>
<html>
<head>
    <title>d3js k-chart</title>
    <meta charset="UTF-8">
</head>

<body>

<div style="width: 520px; height: 220px; margin: 0 auto; text-align: center;">

    <div id="divChart" style="border: 1px solid gray; padding: 10px;">正在加载d3js脚本 ...</div>

    JavaScript脚本来源于 
    <a href="http://jyd.me" target="_blank" style="text-decoration: none;" title="点击在新标签中访问">我来我往的博客</a>
    的
    “<a href="http://blog.jyd.me/ui/k-chart-by-d3.html" target="_blank" style="text-decoration: none;" title="点击在新标签中访问">用D3.js画K线图</a>”
    文章,做了适当修改以适配
    <a href="https://d3js.org" target="_blank" style="text-decoration: none;" title="点击在新标签中访问d3js网站">d3js</a>
    的
    <a href="https://d3js.org/d3.v4.min.js" target="_blank" style="text-decoration: none;" title="可点击鼠标右键,选择‘另存为’以保存该脚本">Version 4</a>
    版本。

</div>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript">

document.getElementById("divChart").innerHTML="";

    // 交易日期,开盘价、最低价、最高价、收盘价、交易量、交易金额
    var EXCHANGE_DATE  = 0,
        PRICE_OPEN     = 1,
        PRICE_MIN      = 2,
        PRICE_MAX      = 3,
        PRICE_CLOSE    = 4,
        EXCHANGE_NUM   = 5,
        EXCHANGE_MONEY = 6;

    var dataset = [
        ['2011-12-16', 25.000, 24.900, 26.800, 26.440, 1171773, 3013978000.00],
        ['2011-12-19', 26.210, 26.000, 27.490, 26.960, 524161, 1393216000.00],
        ['2011-12-20', 27.100, 26.650, 27.590, 26.880, 274802, 744248000.00],
        ['2011-12-21', 27.140, 26.290, 27.650, 26.390, 221804, 599846800.00],
        ['2011-12-22', 25.960, 25.560, 27.200, 26.800, 147229, 386845500.00],
        ['2011-12-23', 26.520, 25.820, 27.170, 27.090, 126590, 337348500.00],
        ['2011-12-26', 26.710, 26.490, 27.320, 26.710, 74700, 200983900.00],
        ['2011-12-27', 26.450, 26.020, 29.380, 27.070, 139441, 385938100.00],
        ['2011-12-28', 26.470, 25.130, 27.420, 27.120, 107477, 284469300.00],
        ['2011-12-29', 26.610, 26.610, 28.300, 28.120, 99828, 277077400.00],
        ['2011-12-30', 27.970, 27.800, 28.690, 27.870, 113659, 320882300.00],
        ['2012-01-04', 27.920, 27.700, 28.550, 27.970, 76590, 215469100.00],
        ['2012-01-05', 27.940, 26.880, 28.420, 27.100, 89823, 248863800.00],
        ['2012-01-06', 26.600, 26.600, 28.210, 28.140, 61342, 168226600.00],
        ['2012-01-09', 28.090, 27.610, 29.550, 29.380, 67159, 192597700.00],
        ['2012-01-10', 29.380, 29.000, 30.300, 30.120, 84051, 250574200.00],
        ['2012-01-11', 29.950, 29.100, 30.200, 29.870, 47952, 142677200.00],
        ['2012-01-12', 29.620, 29.620, 30.950, 30.380, 55554, 168174300.00],
        ['2012-01-13', 30.480, 28.950, 30.580, 29.870, 49726, 147160100.00],
        ['2012-01-16', 29.500, 28.130, 29.770, 28.280, 36006, 105667100.00],
        ['2012-01-17', 28.580, 28.500, 30.920, 30.870, 91777, 271016900.00],
        ['2012-01-18', 30.540, 29.180, 30.900, 29.730, 64588, 195056000.00],
        ['2012-01-19', 29.730, 29.370, 30.600, 30.210, 38141, 115276000.00],
        ['2012-01-20', 30.100, 30.100, 32.220, 31.890, 66314, 207219200.00]
    ];

    var getPrices = function(data) {
        return data.slice(1, 5); // 取 1~4 (开盘价、最低价、最高价、收盘价) 数据
    };
    var getMinPrice = function(d) {
        return d3.min(getPrices(d));
    };
    var getMaxPrice = function(d) {
        return d3.max(getPrices(d));
    };
    var getColor = function(d) {
        // 1-开盘价、4-收盘价
        return (d[PRICE_OPEN] < d[PRICE_CLOSE]) ? 'red' : 'green';
    };

    var dataCnt = dataset.length;
    var w = 500, h = 200;
    var barPadding = 4;
    var svg = d3.select("#divChart").append('svg').attr('width', w).attr('height', h).style("background", "#fcfcfc");
    var priceMin = d3.min(dataset, getMinPrice);
    var priceMax = d3.max(dataset, getMaxPrice);

    var yscale = d3.scaleLinear()
        .domain([priceMin, priceMax])
        .range([0, h]);

    // 画K线
    svg.selectAll('line').data(dataset).enter().append('line')
        .attr('x1', function(d, i) {
                return i * (w / dataCnt) + (w / dataCnt - barPadding) / 2;
        })
        .attr('x2', function(d, i) {
                return i * (w / dataCnt) + (w / dataCnt - barPadding) / 2;
        })
        .attr('y1', function(d, i) {
                return h - yscale(getMaxPrice(d));
        })
        .attr('y2', function(d, i) {
                return h - yscale(getMinPrice(d));
        })
        .attr("stroke", getColor);

    // 画方框
    svg.selectAll('rect').data(dataset).enter().append('rect')
        .attr('x', function(d, i) {
            return i * (w / dataCnt)
        })
        .attr('y', function(d, i) {
            return h - yscale(d3.max([d[PRICE_OPEN], d[PRICE_CLOSE]]));
        })
        .attr('width', function(d, i) {
            return w / dataCnt - barPadding;
        })
        .attr('height', function(d, i) {
            var vv = Math.abs(yscale(d[PRICE_OPEN]) - yscale(d[PRICE_CLOSE]));
            if (vv < 0.5) {
                vv = 0.5; // 防止数据为0或高度过小
            }
            return vv;
        })
        .attr("fill", getColor)
        .attr('title', function(d, i) {
            return "交易日期:" + d[EXCHANGE_DATE] + "&#13;交易量:" + d[EXCHANGE_NUM] + "&#13;交易金额:" + d[EXCHANGE_MONEY];
        });
</script>

</body>
</html>

注意 attr(name, value) 方法 与原文中相应代码的区别。

注:以上代码与原文中的代码相比,做了适当修改,以修正问题 和 做了少量抽象,方便理解。

因在已有功能中使用的是d3js V4版本,没有必要再弄出个V3版本来,因此做出上述修改。

转载于:https://my.oschina.net/yaray/blog/1506719

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值