Skip to content
久久日记本
曾经年少爱追梦,一心只想往前飞
  • 首页
  • 博客
    • 大事记
    • 主题
    • 个人文集
  • 关于
    • 正在读的书
    • 分站
    • 技术作品
    • 联系我
  • 友情链接
  • 留言板
❄
❅
❆
❄
❅
❆
❄
❅
❆
❄
Front-End

使用d3.js绘制图表

Posted on 2014年12月4日 by 九九 / 1764 Views

使用d3.js绘制图表

目录

*什么是d3.js

*d3.js的历史

*效果图

*SVG知识

*如何使用d3.js

*实例和应用

什么是d3.js

D3.js (D3或Data-Driven Documents)是一个用动态图形显示数据的JavaScript库,一个数据可视化的工具。兼容W3C标准,并且利用广泛实现的SVG,JavaScript,和CSS标准。它是早期的Protovis框架的继承者。与其他的类库相比,D3对视图结果有很大的可控性。

d3.js的历史

D3是2011年面世的,同年的8月发布了2.0.0版。到2012年12月,D3已被更新到了3.0.0版。

效果图

折线图

blog

柱状图

blog

饼状图

blog

SVG知识

SVG基础资料

使用SVG绘制折线图

使用SVG绘制柱状图

使用SVG绘制饼状图

我们先来看看饼状图的SVG源码:

<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xml:space="default"
   version="1.1"
   width="100%"
   height="100%" viewBox="0 0 1024 600">
    <defs>
    <script type="text/javascript">
        function ccolor(evt){
            evt.target.parentNode.setAttribute("fill", "white");
        }
        function bcolor(evt,color){
            evt.target.parentNode.setAttribute("fill", color);
        }
    </script>
    </defs>
    <g stroke-width="1" stroke="black">

    <g fill="rgb(45,62,104)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(45,62,104)')">
        <path d="M 502 300 L 802 300 A 300 150 0 0 0 209.5216263454529 266.6218599065528 z"/>
        <path d="M 802 250 A 300 150 0 0 0 209.5216263454529 216.6218599065528 L 209.5216263454529 266.6218599065528 A 300 150 0 0 1 802 300 z"/>
        <path d="M 502 250 L 802 250 A 300 150 0 0 0 209.5216263454529 216.6218599065528 z"/>
    </g>
    <g fill="rgb(124,109,58)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(124,109,58)')">
        <path d="M 502 300 L 209.5216263454529 266.6218599065528 A 300 150 0 0 0 217.62179614986047 347.77299753775264 z"/>
        <path d="M 209.5216263454529 216.6218599065528 A 300 150 0 0 0 217.62179614986047 297.77299753775264 L 217.62179614986047 347.77299753775264 A 300 150 0 0 1 209.5216263454529 266.6218599065528 z"/>
        <path d="M 202 250 A 300 150 0 0 0 217.62179614986047 297.77299753775264 L 217.62179614986047 347.77299753775264 A 300 150 0 0 1 202 300 z"/>
        <path d="M 502 250 L 209.5216263454529 216.6218599065528 A 300 150 0 0 0 217.62179614986047 297.77299753775264 z"/>
    </g>
    <g fill="rgb(203,175,62)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(203,175,62)')">
        <path d="M 502 300 L 217.62179614986047 347.77299753775264 A 300 150 0 0 0 320.8586769023568 419.5698760834384 z"/>
        <path d="M 217.62179614986047 297.77299753775264 A 300 150 0 0 0 320.8586769023568 369.5698760834384 L 320.8586769023568 419.5698760834384 A 300 150 0 0 1 217.62179614986047 347.77299753775264 z"/>
        <path d="M 502 250 L 217.62179614986047 297.77299753775264 A 300 150 0 0 0 320.8586769023568 369.5698760834384 z"/>
    </g>
    <g fill="rgb(33,166,60)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(33,166,60)')">
        <path d="M 502 300 L 716.7600547779157 195.26447728708916 A 300 150 0 0 0 502.00000000000034 150 z"/>
        <path d="M 716.7600547779157 145.26447728708916 A 300 150 0 0 0 502.00000000000034 100 L 502.00000000000034 150 A 300 150 0 0 1 716.7600547779157 195.26447728708916 z"/>
        <path d="M 502 250 L 716.7600547779157 145.26447728708916 A 300 150 0 0 0 502.00000000000034 100 z"/>
    </g>
    <g fill="rgb(115,57,65)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(115,57,65)')">
        <path d="M 502 300 L 768.9615426434407 231.5684013970257 A 300 150 0 0 0 716.7600547779157 195.26447728708916 z"/>
        <path d="M 768.9615426434407 181.5684013970257 A 300 150 0 0 0 716.7600547779157 145.26447728708916 L 716.7600547779157 195.26447728708916 A 300 150 0 0 1 768.9615426434407 231.5684013970257 z"/>
        <path d="M 502 250 L 768.9615426434407 181.5684013970257 A 300 150 0 0 0 716.7600547779157 145.26447728708916 z"/>
    </g>
    <g fill="rgb(218,215,2)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(218,215,2)')">
        <path d="M 502 300 L 775.4517556935018 361.6930654695919 A 300 150 0 0 0 768.9615426434407 231.5684013970257 z"/>
        <path d="M 775.4517556935018 311.6930654695919 A 300 150 0 0 0 768.9615426434407 181.5684013970257 L 768.9615426434407 231.5684013970257 A 300 150 0 0 1 775.4517556935018 361.6930654695919 z"/>
        <path d="M 775.4517556935018 311.6930654695919 A 300 150 0 0 0 802 250 L 802 300 A 300 150 0 0 1 775.4517556935018 361.6930654695919 z"/>
        <path d="M 502 250 L 775.4517556935018 311.6930654695919 A 300 150 0 0 0 768.9615426434407 181.5684013970257 z"/>
    </g>
    <g fill="rgb(193,12,80)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(193,12,80)')">
        <path d="M 502 300 L 604.6060429977004 440.9538931178863 A 300 150 0 0 0 775.4517556935018 361.6930654695919 z"/>
        <path d="M 604.6060429977004 390.9538931178863 A 300 150 0 0 0 775.4517556935018 311.6930654695919 L 775.4517556935018 361.6930654695919 A 300 150 0 0 1 604.6060429977004 440.9538931178863 z"/>
        <path d="M 502 250 L 604.6060429977004 390.9538931178863 A 300 150 0 0 0 775.4517556935018 311.6930654695919 z"/>
    </g>
    <g fill="rgb(62,159,88)" onmouseover="ccolor(evt)" onmouseout="bcolor(evt,'rgb(62,159,88)')">
        <path d="M 502 300 L 320.8586769023568 419.5698760834384 A 300 150 0 0 0 604.6060429977004 440.9538931178863 z"/>
        <path d="M 320.8586769023568 369.5698760834384 A 300 150 0 0 0 604.6060429977004 390.9538931178863 L 604.6060429977004 440.9538931178863 A 300 150 0 0 1 320.8586769023568 419.5698760834384 z"/>
        <path d="M 502 250 L 320.8586769023568 369.5698760834384 A 300 150 0 0 0 604.6060429977004 390.9538931178863 z"/>
    </g>

    </g>
</svg>

这样如果是js生成,这个js会显得十分庞大和复杂,耗费人力物力,这个时候,d3.js就派上用途了。

如何使用d3.js

我们先来看一个效果图,用d3.js绘制一个简单的折线图。。

写了一段js折线图通用方法,一步步来理解每句话意思,

function DrawLine(divid,data,colorline,colorcircle,colorcirclemin,colorX,colorY) {
    ///<summary>绘制折线图</summary>
    ///<param name="divid" type="String">div的id</param>
    ///<param name="data" type="Array">已经转换为对象数组的json数据</param>
    ///<param name="colorline" type="String">折线颜色</param>
    ///<param name="colorcircle" type="String">折线上标记点颜色</param>
    ///<param name="colorcirclemin" type="String">第一个点标记颜色效果</param>
    ///<param name="colorX" type="String">x轴颜色</param>
    ///<param name="colorY" type="String">y轴颜色</param>
    var margin = { top: 100, right: 100, bottom: 100, left: 100 };
    var width = 960 - margin.left - margin.right;
    var height = 460 - margin.top - margin.bottom;

    //时间样式
    var datenew = d3.time.format("%Y-%m-%e %H:%M:%S").parse;

    //横坐标宽度,横坐标为时间
    var x = d3.time.scale().range([0,width]);
    //纵坐标高度,纵坐标为线性数
    var y = d3.scale.linear().range([height, 0]);

    //创建坐标轴生成器
    var xAxis = d3.svg.axis().scale(x)
        .orient("bottom").ticks(5); //X轴范围时间内分的段数,越大精确度越高。
    var yAxis = d3.svg.axis().scale(y)
        .orient("left").ticks(5);//Y轴范围时间内分的段数,越大精确度越高。

    //定义折线上值的数值
    var valuenew = d3.svg.line()
        .x(function (d) { return x(d.date); })
        .y(function (d) { return y(d.value); });//稍后我们再来讲传入的data对象

    //追加html
    var svg1 = d3.select("#chart")
        .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 + ")");

    data.forEach(function (d) {
        d.date = datenew(d.date); //横坐标:转换格式
        //d.value=+d.value;
    });

    //x,y设置范围
    x.domain(d3.extent(data, function (d) { return d.date; }))
    y.domain([0, d3.max(data, function (d) { return d.value; })]);

    //折线
    svg1.append("path")
    //.attr("class", "path")//设置path路径的样式,也可以直接在此设置
        .attr("style", "stroke:" + colorline + ";stroke-width:2;fill:none;")
        .attr("d", valuenew(data)); //stroke: lightgreen;//将新值传入折线


    //在折线的每个标记点画圆圈,这个相当于在svg里面写各种属性,selectAll即帮助我们遍历了整个节点。
    svg1.selectAll("dot")
        .data(data)
        .enter().append("circle")
        .attr("r", "5")//半径
        .attr("cx", function (d) { return x(d.date); })
        .attr("cy", function (d) { return y(d.value); })//所在的点坐标
        .attr("fill",colorcircle)//填充颜色
        .attr("id", function (d, i) {
            //设置圈圈id
            return "dot" + i;//设置圈圈id
        });

    var minIndex = GetMinIndex(data); //data里面最小日期的索引
    var maxIndex = data.length - minIndex - 1; //data里面最大日期的索引

    //最小日期的圈圈效果
    $("#dot" + (minIndex)).css("fill", colorcirclemin);
    svg1.append("circle")
    .attr("r", "3")
    .attr("cx", x(data[minIndex].date))
    .attr("cy", y(data[minIndex].value))
    .attr("fill", "#06A95E");

    //在折线前面加上一部分延长线
    var linePre = "M " + (x(data[minIndex].date) - 50) + "," + y(data[minIndex].value)
    + " L " + x(data[minIndex].date) + "," + y(data[minIndex].value);
    svg1.append("path")
    .attr("d", linePre)
    .attr("style", "stroke: #89E4BB;stroke-width: 1;fill: none;");
    //console.log(linePre);

    //在折线后面加上一部分延长线
    var lineNext = "M " + x(data[maxIndex].date) + "," + y(data[maxIndex].value)
    + " L " + (x(data[maxIndex].date) + 50) + "," + y(data[maxIndex].value);
    svg1.append("path")
    .attr("d", lineNext)
    .attr("style", "stroke: #89E4BB;stroke-width: 1;fill: none;");
    //console.log(lineNext);

    //标识小三角形的索引位置index
    var triangleIndex = 0;
    //在折线后面加上数值备具  时间
    svg1.selectAll("dot")
    .data(data)
    .enter().append("text")
    .attr("x", function (d, i) { return x(d.date) - 10; })
    .attr("y", function (d, i) { return y(d.value) - 10; })
    .text(function (d, i) {
        /*if (i == maxIndex) {
        return " 当前指数"
        }*/
        if (d.desc == "最新数据") {
            triangleIndex = i;
            return "最新数据";
        }
        return " " + DateToDate(d.date);
    })
    .attr("style", "fill:#666666;font-family:@Microsoft Yahei;font-size:10pt;text-align:center;");

    //在折线后面加上数值备具  数值
    svg1.selectAll("dot")
    .data(data)
    .enter().append("text")
    .attr("x", function (d, i) { return x(d.date) - 10; })
    .attr("y", function (d, i) { return y(d.value) - 15 - 10; })
    .text(function (d, i) {
        return d.value;
    })
    .attr("style", "fill:#666666;font-family:@Microsoft Yahei;font-size:14pt;");

    //在折线圈圈“当前指数”点后加上一个小三角
    var triangleNow = (x(data[triangleIndex].date) + 55 - 10) + "," + (y(data[triangleIndex].value) - 10)
        + " " + (x(data[triangleIndex].date) + 55 + 10 - 10) + "," + (y(data[triangleIndex].value) - 10)
        + " " + (x(data[triangleIndex].date) + 55 + 5 - 10) + "," + (y(data[triangleIndex].value) - 8 - 10);
    svg1.append("polygon")
    .attr("points", triangleNow)
    .attr("style", "fill:#06A95E;stroke:#06A95E;stroke-width:1");

    //$("#dot" + (data.length - 1)).append("circle");
    //            .attr("r", "2")
    //            .attr("cx", x(data[data.length - 1].date))
    //            .attr("cy",y(data[data.length-1].value))
    //            .attr("fill","lightgreen");

        //x轴
        svg1.append("g")
            //.attr("class", "x axis")
            .attr("style","fill: none;stroke:"+colorX+";stroke-width: 1;shape-rendering: crispEdges;")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        //y轴
        svg1.append("g")
            //.attr("class", "y axis")
            .attr("style", "fill: none;stroke:"+colorY+";stroke-width: 1;shape-rendering: crispEdges;")
            .call(yAxis);
}

我们再在html引用:

jquery-1.11.1.js,

d3.v3.js

附加点转换方法

function DateToDate(date) {
    ///<summary>将基准时间转为yyyy-MM-dd HH24:mi:ss</summary>
    ///<param name="date" type="String">要转换的时间</param>
    var newdate = new Date(date).getFullYear() + "-" + (parseInt(new Date(date).getMonth()) + 1) + "-" + new Date(date).getDate() + " " + new Date(date).getHours() + ":" + new Date(date).getMinutes() + ":" + new Date(date).getSeconds();
    return newdate.toString();
}
function GetMinIndex(data) {
    ///<summary>获取最小的数据索引</summary>
    ///<param name="date" type="Array">已经格式化成对象的数组集合</param>
    var count = data.length;
    var a = data[0].date;
    var b = data[1].date;
    if (a > b) {
        return data.length - 1;
    } else {
        return 0;
    }
}

写一段方法调用上面的写好的通用折线图方法:

$(document).ready(function () {
    var json = "{\"date\":\"1404548323000\",\"value\":\"98\",\"value2\":\"100\",\"desc\":\"\"}#{\"date\":\"1404461923000\",\"value\":\"91\",\"value2\":\"90\",\"desc\":\"最新数据\"}#{\"date\":\"1404321015337\",\"value\":\"72\",\"value2\":\"0\",\"desc\":\"\"}#{\"date\":\"1404232721740\",\"value\":\"87\",\"value2\":\"89\",\"desc\":\"\"}#{\"date\":\"1404177101616\",\"value\":\"70\",\"value2\":\"82\",\"desc\":\"\"}#{\"date\":\"1404084120285\",\"value\":\"90\",\"value2\":\"93\",\"desc\":\"\"}#{\"date\":\"1403994569503\",\"value\":\"13\",\"value2\":\"20\",\"desc\":\"\"}";
    //将json字符串转换为对象数组
    json = json.split("#");
    var data = new Array();
    for (var i = 0; i < json.length; i++) {
        data[i] = JSON.parse(json[i]);
        data[i].date = DateToDate(parseInt(data[i].date));
    }
    //
    DrawLine("#chart", data, "lightgreen", "mediumseagreen","white","black","black");
});

如此以来,打开页面,我们的折线图(你可以在该项目中检阅demo)呈现在眼前了。

blog

*实例和应用

我在这里一个项目中写了一个实例:

1.蓝V指数 (注:项目已被砍 2016-01-14)

我们再看看d3.js在实例中的应用:

1.MICE

2.QQ群关系可视化查询

版权:2014-12-4 16:54 flyher

D3.js
九九
过去的我们,现在的自己,往事,终会随风而逝。 View all posts by 九九 →

Post navigation

Older post
美剧滑铁卢
Newer post
悲催

标签云

Android AngularJS ASP.NET C# C/C++ CSS Div DX11 GAE Git Java JJProject JS Life MSSQL MVC OpenSource Oracle Python React React-Native Software Tools Vue WCF Web Webpack Website Window WP7 乱记 十年旧梦 天气 小说 工作 情感 故障 散文 日记 游戏开发 电影 网新实训笔记 花落梧桐 诗间集 转载

时光机

  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年5月
  • 2019年12月
  • 2019年10月
  • 2019年9月
  • 2019年6月
  • 2019年5月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年3月
  • 2018年2月
  • 2018年1月
  • 2017年11月
  • 2017年10月
  • 2017年9月
  • 2017年7月
  • 2017年3月
  • 2017年1月
  • 2016年12月
  • 2016年11月
  • 2016年10月
  • 2016年7月
  • 2016年3月
  • 2016年2月
  • 2016年1月
  • 2015年12月
  • 2015年11月
  • 2015年10月
  • 2015年9月
  • 2015年8月
  • 2015年7月
  • 2015年4月
  • 2015年3月
  • 2015年2月
  • 2015年1月
  • 2014年12月
  • 2014年11月
  • 2014年10月
  • 2014年9月
  • 2014年8月
  • 2014年7月
  • 2014年6月
  • 2014年5月
  • 2014年4月
  • 2014年3月
  • 2014年2月
  • 2014年1月
  • 2013年12月
  • 2013年11月
  • 2013年10月
  • 2013年9月
  • 2013年8月
  • 2013年7月
  • 2013年6月
  • 2013年5月
  • 2013年4月
  • 2013年3月
  • 2013年1月
  • 2012年11月
  • 2012年10月
  • 2012年9月
  • 2012年8月
  • 2012年7月
  • 2012年6月
  • 2012年5月
  • 2012年4月
  • 2012年3月
  • 2012年2月
  • 2012年1月
  • 2011年12月
  • 2011年11月
  • 2011年10月
  • 2011年9月
  • 2011年8月
  • 2011年6月
  • 2011年5月
  • 2011年4月
  • 2011年3月
  • 2011年2月
  • 2010年12月
  • 2010年11月
  • 2010年10月
  • 2010年9月
  • 2010年8月
  • 2010年6月
  • 2010年5月
  • 2010年2月
  • 2010年1月
  • 2009年12月
  • 2009年11月
  • 2009年10月
  • 2009年9月
  • 2009年8月
  • 2009年7月
  • 2009年6月
  • 2009年5月
  • 2009年4月
  • 2009年3月
  • 2009年2月
  • 2009年1月
  • 2008年8月
  • 2008年6月
  • 2008年5月
  • 2008年4月
  • 2008年2月
  • 2007年11月
  • 2007年8月
  • 2007年6月
  • 2007年5月
  • 2007年4月
  • 2007年3月
  • 2007年2月
  • 2007年1月
  • 2006年10月
  • 2006年8月
© 2006 - 2021 久久日记本
Powered by WordPress | Theme: Graphy for 99diary