zoukankan      html  css  js  c++  java
  • d3

    //4 选择集与数据
    //4.1 选择元素
    //select:返回选择器的第一个元素
    //selectAll:返回选择器的所有元素
    d3.select('body');
    d3.select('#footer');
    d3.select('.content');//选择类为content的第一个元素
    d3.selectAll('p');
    d3.selectAll('.content');
    d3.selectAll('ul li');
    d3.select('body').selectAll('p');

    //4.2 选择集
    //d3.select和d3.selectAll返回的对象称为选择集(selection),添加/删除/设定网页中的元素,都要使用选择集
    selection.empty();//如果选择集为空,返回true,否则返回false
    selection.node();//返回第一个非空元素,如果选择集为空,返回null
    selecttion.size();//返回选择集中的元素个数

    selection.attr(name[, value]);//设定或获取属性
    svg.append('circle').attr('cx','50px').attr('cy','50px').attr('r','50px').attr('fill','red');

    selection.classed(name[,value]);//设定或获取选择集的CSS类,name为类名,value为布尔值,表示该类是否开启
    d3.select('p').attr('class', 'red bigsize');
    d3.select('p').classed('red', true).attr('classed', false);
    d3.select('p').classed({'red':true, 'bigsize':true});
    d3.select('p').classed('red bigsize', true);
    console.log(d3.select('p').classed('bigsize'));//返回该类是否开启

    selection.style(name[, value[, priority]]);//设定或获取选择集的样式
    d3.select('p').style('color', 'red').style('font-size', '30px');
    d3.select('p').style({'color':'red', 'font-size':'30px'});

    selection.property(name[, value]);//设定或获取选择集的属性
    //返回不能用attr()来处理的属性,都可用property()。例如文本框的value属性,复选框等
    d3.select('input').property('value');
    d3.select('input').property('value', 'aaa');

    d3.text([value]);//设定或获取选择集的文本内容,相当于innerText
    d3.html([value]);//设定或获取选择集内部html内容,相当于innerHTML

    //4.3 添加/插入/删除
    selection.append(name);//在选择集的末尾添加一个元素,name为元素名称
    selection.insert(name[, before]);//在选择集中指定元素之前插入一个元素,name为被插入的元素名称,before为CSS选择器名称
    selection.remove();//删除选择集中的元素
    d3.select('body').append('p').text('bike');
    d3.select('body').insert('p', '#plane').text('bike');
    d3.select('body').select('#plane').remove();

    //4.4 数据邦定
    //数据邦定,就是使被选择元素里"含有"数据
    selection.datum([value]);//选择集中每一个元素都邦定相同的数据value
    selection.data([values[, key]]);//选择集中每一个元素分别邦定数组values的每一项。key是一个键函数,用于指定邦定数组时对应规则
    var p = d3.select('body').selectAll('p');
    p.datum(7);
    console.log(p.datum());
    //问题?数据被邦定在选择集上后,该如何使用?
    d3.select('body').selectAll('p').datum("mmm").text(function(d,i){return d + " " + i;});
    //无名函数的参数d为被邦定的字符串,i为索引号
    //在被邦定数据的选择集中添加元素后,新元素会继承该数据
    d3.select('body').selectAll('p').datum("mmm").append('span').text(function(d,i){return d + " " + i;});

    //data()的工作过程
    //data()能够将数组各项分别邦定到选择集的各元素上,并且能制定邦定规则。当数组长度与元素数量不一致时,data()也能够处理。
    //当数组长度大于元素数量时,为多余数据预留元素位置,以便将来插入新元素;当数组长度小于元素数量时,能够取多余元素的位置,以便将来删除。
    var dataset = [3,6,9];
    var p = d3.select('body').selectAll('p');
    var update = p.data(dataset);
    console.log(update);
    console.log(update.enter());
    console.log(update.exit());
    //update: 数组长度 = 元素数量。则邦定数据的元素"即将被更新(update)"
    //enter: 数组长度 > 元素数量。则部分还不存在的元素"即将进入可视化(enter)"
    //exit: 数组长度 < 元素数量。则多余的元素"即将退出可视化(exit)"

    //邦定的顺序
    //默认情况下,data()是按照索引号顺序邦定的:第0个元素邦定数组的第0项。也可不按此顺序,需要用到data()的第二个参数,是一个函数,称为键函数(key function).
    //注意:只有在选择集已经邦定有数据的情况下,使用键函数才有效果。
    var persons = [{id:3, name:"jack"}, {id:9, name:"rose"}, {id:6, name:"vita"}];
    var p = d3.select('body').selectAll('p');
    p.data(persons).text(function(d){ return d.id + ":" + d.name; });
    p.data(persons, function(d){ return d.id; }).text(function(d){ return d.id + ":" + d.name; });//表示使用数组项的id作为键

    //4.5 选择集的处理
    //当数组长度与元素数量不一致时,有enter部分和exit部分,前者表示存在多余的数据,后者表示存在多余的元素。
    //问题:那么如果处理这些多余的东西呢?
    //4.5.1 enter的处理方法
    //如果没有足够的元素,那么处理方法就是添加元素。
    var dataset = [3,6,9];
    var p = d3.select('body').selectAll('p');
    var update = p.data(dataset);
    var enter = update.enter();
    update.text(function(d){ return d;});//update部分的处理方法是直接修改内容
    enter.append('p').text(function(d){ return d;});//enter部分的处理方法是添加元素后再修改内容

    //通常冲服务器读取数据后,网页中没有与之对应的元素。因此,有一个常见的用法:选择一个空集,然后使用enter().append()形式来添加足够的元素。
    var dataset = [10,20,30,40,50];
    var body = d3.select('body');
    body.selectAll('p').data(dataset).enter().append('p').text(function(d){ return d;});//假设body中没有p元素

    //4.5.1 exit的处理方法
    //如果存在多余的元素,没有与之对应的数据,那么就删除元素。使用remove()即可删除元素
    var dataset = [3,6,9];
    var p = d3.select('body').selectAll('p');
    var update = p.data(dataset);
    var exit = update.exit();
    update.text(function(d){ return d;});
    exit.remove();

    //4.5.3 处理模板
    //有时不知道数据多还是元素多,但是处理方法都是类似的。因此,可归纳为一个模板,用户不必理会数组长度和元素数量之间的关系
    var dataset = [3,6,9];
    var p = d3.select('body').selectAll('p');
    var update = p.data(dataset);
    var enter = update.enter();
    var exit = update.exit();
    update.text(function(d){ return d;});
    enter.append('p').text(function(d){ return d;});
    exit.remove();

    //4.5.4 过滤器
    //根据条件选择选择集中的一部分子集,该方法称为过滤器
    selection.filter(function(d,i){ if(d>20){return true;}else{return false;}});

    //4.5.5 选择集的顺序
    //sort()可以根据 被邦定数据 重新排序选择集中的元素。sort()的参数是一个无名函数,该函数成为比较器。如果不指定比较函数,则默认为d3.ascending
    selection.sort(function(a,b){return b - a; });

    //4.5.6 each()的应用
    //each()允许对选择集的各个元素跟别处理
    var persons = [{id:1001, name:'zhangsan'}, {id:1002, name:'lisi'}];
    var p = d3.select('body').selectAll('p');
    p.data(persons).each(function(d,i){d.age=20;}).text(function(d){ return d.id + " " + d.name + " " + d.age;});

    //4.5.7 call()的应用
    //call()允许将选择集自身作为参数,传递给某一函数。拖拽/缩放等操作,会用到call()
    d3.selectAll('div').call(myfun);
    function myfun(selection){
    selection.attr('name', 'value');
    }
    myfun(d3.selectAll('div'));

    //4.6 数组的处理


    //4.7 柱状图的制作
    //柱状图(Bar Chart)是使用柱形的长短来表示数据变化的图标。包含:矩形/坐标轴和文字。
    var dataset = [50, 43, 120, 87, 99, 167, 142];//数组长度为矩形的个数,数组项为矩形的高度
    var width = 400;
    var height = 400;
    var svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
    var padding = {top:20, right:20, bottom:20, left:20};//定义上下左右的边框
    var rectStep = 35;//矩形所占的宽度(包括空白)
    var rectWidth = 35;//矩形所占的宽度(不包括空白)

    //padding表示svg绘制区域内一段空白的高度,这样做可以防止某些图形元素绘制到svg区域的外部。
    var rect = svg.selectAll('rect').data(dataset).enter().append('rect')
    .attr('fill', 'steelbule')
    .attr('x', function(d, i){ return padding.left + i*rectStep; })
    .attr('y', function(d){ return height-padding.bottom - d; })
    .attr('width', rectWidth)
    .attr('height', function(d){return d;});
    //为矩形添加文字
    //为使每一个<text>元素正好显示在每个矩形的正中心,设置了元素的text-anchor/x/y/dx/dy五个属性
    //dy/dy表示相对(x,y)平移大小,文本会在(x+dx, y+dy)开始显示
    //text-anchor:start(文字第一个字读位于起始位置的右方), middle(文字的中心位于起始位置), end(文字最后一个字符靠近起始位置)
    var text = svg.selectAll('text').data(dataset).enter().append('text')
    .attr('fill', 'white')
    .attr('font-size', '14px')
    .attr('text-anchor', 'middle')
    .attr('x', function(d, i){ return padding.left + i*rectStep; })
    .attr('y', function(d){ return height-padding.bottom - d; })
    .attr('dx', rectWidth/2)
    .attr('dy', "1em")
    .text(function(d){return d;});

    //4.7.2 更新数据
    //有时需要更新数据,更新后柱状图也跟着变化。例如将数据排序/增加新数据等,都需要柱状图跟着变化
    function draw(){
    var udapteRect = svg.selectAll('rect').data(dataset);
    var enterRect = udapteRect.enter();
    var exitRect = udapteRect.exit();

    var updateText =svg.selectAll('text').data(dataset);
    var enterText = updateText.enter();
    var exitText = updateText.exit();

    //将绘制图形的代码写在一个函数draw(),当数据发生更新时,再次调用此函数即可
    updateRect.attr('fill', 'steelbule')
    .attr('x', function(d, i){ return padding.left + i*rectStep; })
    .attr('y', function(d){ return height-padding.bottom - d; })
    .attr('width', rectWidth)
    .attr('height', function(d){return d;});

    enterRect.append('rect')
    .attr('fill', 'steelbule')
    .attr('x', function(d, i){ return padding.left + i*rectStep; })
    .attr('y', function(d){ return height-padding.bottom - d; })
    .attr('width', rectWidth)
    .attr('height', function(d){return d;});

    exitRect.remove();
    }

    //<button type="button" onclick="mysort()">sort</button>
    //<button type="button" onclick="myadd()">add data</button>
    function mysort(){
    dataset.sort(d3.ascending);
    draw();
    }
    function myadd(){
    dataset.push(Math.floor(Math.random()*100));
    draw();
    }

    //5. 比例尺和坐标轴
    //5.1 定量比例尺
    //线性函数 y=2x+1 , x的范围[0,2]称为该函数的定义域,y的范围为值域
    //D3种提供了很多比例尺,适用于各种计算。每个比例尺都需要指定一个domain(定义域)和range(值域)
    //D3种的比例尺可当作函数使用,调用时传入参数
    var linear = d3.scale.linear()//创建一个线性比例尺,该比例尺相当于数学中的: y=1/5x, 0<=x<=500
    .domain([0,500])//定义域
    .range([0,100]);//值域
    console.log(linear(50));//10
    console.log(linear(250));//50
    console.log(linear(450));//90

    //5.1.1 线性比例尺(Linear Scale)
    d3.scale.linear() :创建线性比例尺
    linear(x) :输入定义域值x,返回对应值域的值
    linear.invert(y) :输入值域值y,返回对应定义域的值
    linear.domain([numbers]) :设置或获取定义域
    linear.range([values]) :设置或获取值域
    linear.rangeRound([values]) :代替range()使用的话,比例尺输出值会进行四舍五入的运算,结果为整数
    linear.clamp([values]) :默认false,该比例尺接收一个超出定义域范围内的值是,依然能计算得到值(可能超出值域)。设置true,任何超出值域范围的值,都被收缩到值域范围内
    linear.nice([count]) :
    linear.ticks([count])
    linear.tickFormat(count, [format])

    //5.1.2 指数和对数比例尺

    //5.1.3 量子和分位比例尺

    //5.1.4 阈值比例尺

    //5.2 序数比例尺(Ordinal Scale),定义域和值域都是离散的
    d3.scale.ordinal() 创建一个序数比例尺
    ordinal(x) 输入一个定义域内地俄离散值,返回值域内一个离散值
    ordinal.domain([values]) 设定或获取定义域
    ordinal.range([values]) 设定或获取值域
    ordinal.rangePoints(interval[, padding]) 代替range()设定值域。接收一个连续的区间,然后根据定义域中离散值的数值将其分段,分段值即作为值域的离散值
    ordinal.rangeRoundPoints(interval[, padding]) 和rangePoints()一样,但会将结果取整
    ordinal.rangeBands(interval[, padding[, outerPadding]]) 代替range()设定值域。和rangePoints()一样,也接收一个连续的区间,然后根据定义域中离散值的数量将其分段,但是其分段方法不同
    ordinal.rangeRoundBands(interval[, padding[, outerPadding]]) 和rangeBands()一样,但会将结果取整
    ordinal.rangeBand() 返回使用rangeBands()设定后每一段的宽度
    ordinal.rangeExtend() 返回一个数组,数组里存有值域的最大值和最小值

    var ordinal = d3.scale.ordinal().domain([1,2,3,4,5]).range([10,20,30,40,50]);
    console.log(ordinal(1));//10
    console.log(ordinal(2));//20
    console.log(ordinal(5));//50
    console.log(ordinal(8));//输入值不在定义域中,输出10

    var rodinal = d3.scale.ordinal().domain([1,2,3,4,5]).rangePoints([0,100]);//inteval:[0,100], padding:0, step:25
    console.log(ordinal.range());//[0,25,50,75,100]
    console.log(ordinal(1));//0
    console.log(ordinal(3));//50
    console.log(ordinal(5));//100

    rodinal.rangePoints([0,100], 5);//interval:[0,100], padding:5, step:11.11111。则step*padding/2=27.77777,是输出数组的第一个值
    console.log(ordinal.range());

    rodinal.rangeRoundPoints([0,100], 5);
    console.log(ordinal.range());

    var bands = d3.scale.rodinal().domain([1,2,3,4,5]).rangeBands([0,100]);
    console.log(bands.range());//[0,20,40,60,80]
    console.log(bands.rangeBand());//20

    //D3提供了几个获取颜色的序数比例尺。如果对颜色没有特殊要求直接使用这些颜色比例尺即可
    d3.scale.category10();//10种颜色
    d3.scale.category20();//20种颜色
    d3.scale.category20b();//20种颜色
    d3.scale.category20c();//20种颜色

    var color = d3.scale.category10();
    console.log(color(1));
    console.log(color('zhangsan'));

    var width = 600;
    var height = 600;
    var dataset = d3.range(5);//[0,1,2,3,4,5]
    var color = d3.scale.category10();
    var svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
    var circle = svg.selectAll('circle').data(dataset).enter().append('circle')
    .attr('cx', function(d,i){return 30 + i*80;})
    .attr('cy', 100)
    .attr('r', 30)
    .attr('fill', function(d,i){return color(i)});

    //5.3 坐标轴(Axis)
    d3.svg.axis() 创建一个默认的新坐标轴
    axis(selection) 将此坐标轴应用到指定的选择集上,该选择集需要包含有<svg>或<g>元素
    axis.scale([scale]) 设定或获取坐标轴的比例尺
    axis.orient([orientation]) 设定或获取坐标轴的方向,有四个值: top,bottom,left,right。top表示水平坐标轴的刻度在直线下方,left表示垂直坐标轴的刻度在直线右方
    axis.ticks([argument...]) 设定或获取坐标轴的分隔数,默认10。例如,设定5,则坐标轴上刻度数量为6,分段数5。这个函数会调用比例尺的ticks()
    axis.tickValues([values]) 设定或获取坐标轴的指定刻度。例如,参数为[1,2,3,6,7,8],则在这几个值上会有刻度
    axis.tickSize([inner, outer]) 设定或获取坐标轴的内外刻度的长度。默认6
    axis.innerTickSize([size]) 设定或获取坐标轴的内刻度的长度。内刻度指不是两端的刻度
    axis.outerTickSize([size]) 设定或获取坐标轴的外刻度的长度。外刻度指两端的刻度
    axis.tickFormat([format]) 设定或获取刻度的格式

    //5.3.1 绘制方法
    //坐标轴的主直线由<path>绘制,刻度由<line>绘制,刻度上的文字由<text>绘制
    var width = 600;
    var height = 600;
    var svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
    var xScale = d3.scale.linear().domain([0,10]).range([0,300]);
    var axis = d3.svg.axis().scale(xScale).orient('bottom');
    var gAxis = svg.append('g')//在svg中添加一个包含坐标轴各元素的g元素
    .attr('transform', 'translate(80,80)');//平移到(80,80)
    axis(gAxis);//在gAxis中绘制坐标轴
    //坐标轴的所有图形元素需放入<svg>或<g>里,建议新建g来控制,而不要直接放在<svg>中,svg中通常还包含其它图形元素。
    //绘制后,html的元素结构中,class为tick的<g>元素是刻度,每一个刻度里都包含了<line>和<text>。坐标轴的主直线式最下方的class为domain的<path>

    .axis path,
    .axis line{
    fill:none;
    stroke:black;
    stroke-rendering:criapEdges;
    }
    .axis text{
    font-family:sans-serif;
    font-size:11px;
    }

    gAxis.attr('class', 'axis');
    gAxis.call(axis);//这种方式很常见

    //5.3.2 刻度
    //刻度的方向,间隔,长度,文字格式等
    //如果要设置在什么值上标出刻度,使用ticks()和tickValues()
    var axisLeft = d3.svg.axis().scale(scale).orient('left').ticks(5);
    var axisRight = d3.svg.axis().scale(scale).orient('right').tickValues([3,4,5,6,7]);

    var axisTop = d3.svg.axis().scale(scale).orient('top').ticks(5)
    .tickSize(2,4);//设置两端刻度长度大于内部。第一个参数为内部刻度的直线长度,第二个为首尾刻度长度。也可使用innerTickSize()和outerTickSize()

    //5.3.2 各种比例尺的坐标轴
    var linear = d3.scale.linear().domain([0,1]).range([0,500]);
    var pow = d3.scale.pow().exponent(2).domain([0,1]).range([0,500]);
    var log = d3.scale.log().domain([0,1]).range([0,500]);

    //5.4 柱形图的坐标轴
    var xAxisWidth = 300;
    var yAxisWidth = 300;
    var xScale = d3.scale.oridinal()
    .domain(d3.range(dataset.length))//[0,1,2,3...]
    .rangeRoundBands([0, xAxisWidth], 0.2);
    var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset)])
    .range([0, yAxisWidth]);
    .attr('x', function(d,i){ return padding.left + xScale(i)});
    .attr('y', function(d){return height - padding.bottom - yScale(d)});
    var xAxis = d3.svg.axis().scale(xScale).orient('bottom');
    yScale.range([yAxisWidth, 0]);//重新设置y轴比例尺,与原来相反
    var yAxis = d3.svg.axis().scale(yScale).orient('left');
    svg.append('g')
    .attr('class', 'axis')
    .attr('transform','translate(' + padding.left + ',' + (height - padding.bottom) + ')')
    .call(xAxis);

    //5.5 散点图制作(Scatter Chart)

  • 相关阅读:
    分析Ajax并爬取微博列表
    链表01
    Install ping command from ubuntu docker
    In container,I can't use man
    centos install glances
    centos 服务器命令下安装GUI
    firefox浏览器配置
    xshell替代产品
    Linux下将一个文件压缩分包成多个小文件
    Linux生成大文件
  • 原文地址:https://www.cnblogs.com/skorzeny/p/6740184.html
Copyright © 2011-2022 走看看