D3.js(3) path/折线图

这篇具有很好参考价值的文章主要介绍了D3.js(3) path/折线图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概念

path 元素是用来绘制各种形状(例如线条、曲线、弧形、圆弧等)的元素。path 元素的 d 属性用来定义绘制的路径。具体来说,d 属性是一个字符串,包含一系列的命令和参数,用来描述路径的形状。

1.1 d属性

M=moveto(M x,y) 将画笔移到相对于svg的坐标位置
L=lineto(L x,y) 画直线到指定的坐标位置
H=horizontal lineto(H x) 画水平线到指定x坐标位置
V=vertical lineto(V y) 画垂直线到指定的y坐标位置
Z=closepath() 关闭路径
<svg>
  <path d="M 10 10 L 100 10 L 100 100 L 10 100 Z" />
</svg>
  • M 10 10 表示将画笔移动到坐标为 (10, 10) 的点。
  • L 100 10 表示从当前点绘制一条直线到坐标为 (100, 10) 的点。
  • L 100 100L 10 100 依次表示绘制两条直线。
  • Z 表示关闭路径,即从当前点绘制一条直线到路径的起点,完成矩形的绘制。

1.2 path生成器

d3.line().x().y()//折线图

d3.geoPath().projection()//用于地图

d3.area()// 绘制平面

d3.arc().innerRadius().outerRadius() //饼图

d3.lineRadial().angle().radius() //极坐标系

文档:https://github.com/d3/d3-shape/tree/v1.3.7

案例 

调试的时候把定时器的时间设置的比transition短很多,感觉图像每次都没画到位,在这停了好久。。太蠢了。。

最后那个所有折线的汇总和颜色标签是修改了源代码自己添加的效果,学有成效就好~

<!DOCTYPE html>
<html>
  <head>
    <title>Line</title>
    
  </head>
  <body>
    <svg width="1600" height="800" id="mainsvg" class="svgs"></svg>
    <script src="/static/js/d3.min.js"></script>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script>
      const svg = d3.select('#mainsvg');
      const width = +svg.attr('width');
      const height = +svg.attr('height');
      const margin = {top: 120, right: 160, bottom: 50, left: 150};
      const innerWidth = width - margin.left - margin.right;
      const innerHeight = height - margin.top - margin.bottom;
      const g = svg.append('g').attr('id', 'maingroup')
      .attr('transform', `translate(${margin.left}, ${margin.top})`);
      const xValue = (datum) => {return datum['日期']};
      const yValue = (datum) => {return datum['现有确诊']};
      let xScale, yScale; 
      let alldates;
      let allkeys; 
      const yAxisLabel = '现有确诊人数';

      const colors = [
        '#FF0000', '#FFA500', '#FFFF00', '#008000', '#00FFFF', '#0000FF', '#FF00FF',
        '#800080', '#C0C0C0', '#808080', '#800000', '#FFD700', '#00FF00', '#00CED1',
        '#1E90FF', '#ADD8E6', '#FFC0CB', '#FA8072', '#FFA07A', '#FF69B4', '#8B008B',
        '#EE82EE', '#8FBC8F', '#3CB371', '#BDB76B', '#CD5C5C', '#F0E68C', '#7B68EE',
        '#4169E1', '#A0522D', '#2F4F4F', '#D3D3D3', '#4682B4'
      ];

      const provinces1 = ["安徽","澳门","北京","福建","甘肃","广东","广西","贵州",
        "海南","河北" ,"河南","黑龙江","湖南" ,"吉林","江苏","江西","辽宁","内蒙古",
        "宁夏","青海","山东","山西","陕西","上海","四川","台湾","天津","西藏","香港",
        "新疆","云南","浙江","重庆"
      ]


      const render_init = function(data){
        xScale = d3.scaleTime() //与scaleLiner()相似,但是domain必须是日期
        .domain(d3.extent(data, xValue))
        .range([0, innerWidth])
        .nice();

        yScale = d3.scaleLinear()
        .domain([d3.max(data, yValue), d3.min(data, yValue)])
        .range([0, innerHeight])
        .nice();

        // Adding axes
        const xAxis = d3.axisBottom(xScale)
        .ticks(Math.floor(alldates.length) / 4)
        //.tickFormat(d3.timeFormat('%b-%d'))
        .tickSize(-innerHeight)
        const xAxisGroup = g.append('g').call(xAxis)
        .attr('transform', `translate(0, ${innerHeight})`);

        const yAxis = d3.axisLeft(yScale).tickSize(-innerWidth);
        const yAxisGroup = g.append('g')
        .call(yAxis)
        .append('text')
        .attr('font-size', '2em')
        .attr('transform', `rotate(-90)`)
        .attr('x', -innerHeight / 2)
        .attr('y', -60)
        .attr('fill', '#333333')
        .text(yAxisLabel)
        .attr('text-anchor', 'middle') // Make label at the middle of axis. 
        yAxisGroup.selectAll('.domain').remove(); // we can select multiple tags using comma to seperate them and we can use space to signify nesting; 
            

        g.selectAll('.tick text').attr('font-size', '2em');
        g.append('path').attr('id', 'alterPath');

        
        let legend = d3.select('#maingroup').selectAll(".legend")
        .data(provinces1)
        .enter().append("g")
        .attr("class", "legend")
        .attr("transform", function(d, i) { 
          if(i >= 20)return "translate(" + (innerWidth + 90) + "," + ((i - 20) * 25) + ")"
          return "translate(" + (innerWidth + 10) + "," + (i * 25) + ")"; });
      
        // draw legend colored rectangles
        legend.append("rect")
        .datum(provinces1) 
        .attr("x", 0)
        .attr("y", 0)
        .attr("width", 20)
        .attr("height", 20)
        .style("fill", function (d,i) {return colors[i]});

        // draw legend text
        legend.append("text")
        .datum(provinces1) 
        .attr('class', 'legend_text')
        .attr("x", 30)
        .attr("y", 9)
        .attr("dy", ".5em")
        .style("text-anchor", "start")
        .text(function (d,i) { return provinces1[i]});
      }; 

      // const render_update = function(data){
      //     const line = d3.line()
      //     .x(d => {return xScale(xValue(d))})
      //     .y(d => {return yScale(yValue(d))})
      //     .curve(d3.curveCardinal.tension(0.5))

      //     // lineEmpty is typically used for the first animation that raise the line up; 
      //     const lineEmpty = d3.line()
      //     .x(d => {return xScale(xValue(d))})
      //     .y(d => {return yScale(0)})
      //     .curve(d3.curveCardinal.tension(0.5))

      //     const maingroup = d3.select('#maingroup');
      //     const pathupdate = maingroup.selectAll('.datacurve').data([data])
          
      //     const pathenter = pathupdate.enter().append('path')
      //     .attr('class', 'datacurve')
      //     .attr("fill", "none") 
      //     .attr("stroke", "steelblue")
      //     .attr("stroke-width", 2.5)
      //     .attr("d", lineEmpty)

      //     pathupdate.merge(pathenter)
      //     .transition().duration(2000).ease(d3.easeLinear)
      //     .attr("d", line)
      // };

      const render_update_alter = function(data, color){
        console.log(data)
        const line1 = d3.line()
          .x(d => {return xScale(xValue(d))})
          .y(d => {return yScale(yValue(d))})
          //.curve(d3.curveBasis)
          .curve(d3.curveCardinal.tension(0.5)) //把离散点连成线

        // See https://github.com/d3/d3-shape/blob/v1.3.7/README.md#curves
        d3.select('#alterPath').datum(data) //data()绑定的是数组 datum()绑定的是单个数据
        .attr('class', 'datacurve')
        .attr("fill", "none") //设置填充为无
        .attr("stroke", color) //画笔颜色
        .attr("stroke-width", 1.5) //画笔宽度
        .transition().duration(2000) //这个要设置的比定时器时间短
        .attr("d", line1) //line的输入就是数据绑定的图元

        province = data[0]['省份'];
        g.selectAll('.province_text').remove();
        g.append("text")
        .data(data) 
        .attr('class', 'province_text')
        .attr("x", innerWidth / 4)
        .attr("y", - 20)
        .style("text-anchor", "end")
        .attr("fill", "lightskyblue")
        .attr('font-size', '4em')
        .attr('font-weight', 'bold')
        .text('省份:'+province);
      }

      const renderEnd = function(data, color){
        const line = d3.line()
          .x(d => {return xScale(xValue(d))})
          .y(d => {return yScale(yValue(d))})
          //.curve(d3.curveBasis)
          .curve(d3.curveCardinal.tension(0.5))

        g.append('path').datum(data) //data()绑定的是数组 datum()绑定的是单个数据
        .attr("class", "datacurve")
        .attr("fill", "none") //设置填充为无
        .attr("stroke", color) //画笔颜色
        .attr("stroke-width", 1.5) //画笔宽度
        .attr("d", line) //line的输入就是数据绑定的图元


      }

      d3.csv('./province.csv').then(function(data){

        //暂时删除湖北 数据太大会影响比例
        data = data.filter(datum => {return datum['省份'] !== '总计'}); 
        data = data.filter(datum => {return datum['省份'] !== '湖北'}); 
        //日期要单独拿出来做横轴的比例尺
        alldates = Array.from(new Set( data.map( d => xValue(d) ) ));

        //数据类型转换
        data.forEach( datum => {
          datum['现有确诊'] = +(datum['现有确诊']);
          datum['日期'] = new Date(datum['日期']);
        } ); 

        let provinces = {}; 
        allkeys = Array.from(new Set( data.map( d => d['省份'] ) ))
        console.log(allkeys)
        allkeys.forEach( key => {provinces[key] = []} );
        //数据按照省份归类
        data.forEach( d => { provinces[d['省份']].push(d) } )
        //确保每个省份的数据按照日期顺序排序
        allkeys.forEach( key => provinces[key].sort(function(a,b){
              return a['日期'] - b['日期'];
        })); 
        render_init(data);
        let c = 0;
        let intervalId = setInterval(() => {
            if(c >= allkeys.length){
                clearInterval(intervalId);
                g.selectAll('.province_text').remove();
                g.selectAll('#alterPath').remove();
                let i = 0
                allkeys.forEach(item => {
                  renderEnd(provinces[item],colors[i])
                  i++
                })
            }else{
                let key = allkeys[c];
                render_update_alter(provinces[key], colors[c]);
                c = c + 1;
            }
        }, 3000);
      });

    </script>
  </body>
</html>

D3.js(3) path/折线图

 文章来源地址https://www.toymoban.com/news/detail-423697.html

到了这里,关于D3.js(3) path/折线图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 13. unity粒子特效--发射模块、各种发射器形状、粒子渐变(颜色/大小)

    1. 发射模块(Emission) 匀速发射 : Rate over Time :每秒钟发射的粒子数 Rate over Distance :每移动一米发射的粒子个数 两者可指定其一:若仅指定 Rate over Time ,则粒子根据时间的变化进行发射,若仅指定 Rate over Distance ,则粒子系统每词移动时才发射,不移动不发射 爆发式发射

    2024年02月15日
    浏览(47)
  • d3d12龙书阅读----绘制几何体(上)

    本节主要介绍了构建一个简单的彩色立方体所需流程与重要的api 下面主要结合立方体代码分析本节相关知识 输入装配器阶段的输入 首先,我们需要定义立方体的八个顶点 顶点结构体: 当然,对于更复杂的情况,我们不仅要定义顶点的位置与颜色,还要包括法线向量、纹理

    2024年03月27日
    浏览(58)
  • python绘制折线图

            俗话说,“字不如表,表不如图”,图表在数据分析中的作用不言而喻。python中有pandas和matplotlib两个库供使用者来绘制图表。下面来绘制“成绩表.xlsx”的折线图。  废话不多说,直接上代码: 对上述重要函数的参数进行详细讲解: plot函数:以plt.plot(x,y2,label=

    2024年02月11日
    浏览(50)
  • Matlab绘制箱线图

    目录 1.箱线图例子1  2.绘制无颜色的箱线图例子  当需要绘制无颜色的箱线图时,内部采用线条填充 但是:填充简单图例不好整,所以图例是再手动绘制的图例,需要慢慢调整

    2024年02月16日
    浏览(38)
  • PyLab绘制曲线图

    PyLab 是一个面向 Matplotlib 的绘图库接口,其语法和 MATLAB 十分相近。它和 Pyplot 模快都够实现 Matplotlib 的绘图功能。PyLab 是一个单独的模块,随 Matplotlib 软件包一起安装,该模块的导包方式和 Pyplot 不同,如下所示: PyLab 是一个很便捷的模块,下面对它的使用方法做相应的介绍

    2024年02月16日
    浏览(55)
  • 【Matplotlib 绘制折线图】

    在数据可视化中,折线图是一种常见的图表类型,用于展示随着变量的变化,某个指标的趋势或关系。Python 的 Matplotlib 库为我们提供了方便易用的功能来绘制折线图。 下面的代码展示了如何使用 Matplotlib 绘制一个折线图,使用两组数据 y1 和 y2 ,分别表示不同天数的温度变化

    2024年02月15日
    浏览(38)
  • python绘制股票k线图

    使用python绘制股票k线图 1. 需要安装的包 tushare matplotlib mpl_finance datetime 使用Anaconda Prompt安装,安装语句’pip install 包的名字’ 2. 获取数据 使用tushare包导入数据 第一个参数’000002‘为股票代码,第二个参数start表示起始时间,第三个参数end表示结束日期。 获取的数据df为Da

    2024年02月06日
    浏览(38)
  • Qt---多线程绘制折线图

    Qt多线程绘制折线图 需求:在ui中绘制折线图,需要在子线程中操作ui界面上的对象。因为子线程中创建图形化相关的不被允许,因此【思路1:】在子线程中仅仅读取数据,进行数据处理,将数据处理的结果返回给主线程,主线程操作ui界面进行绘制折线图。【思路2:】将u

    2024年02月14日
    浏览(40)
  • 【Python】Matplotlib绘制折线图

    1.Matplotlib画图简单实现 Matplotlib在一个绘制2D图片的库 2.折线图 2.1绘制折线图 接下来逐步对折线图进行修改 2.2设置线的格式 2.3设置折点 2.4.图片的保存和导出 2.5设置刻度 2.6显示中文 matplotlib只显示应为,无法显示中文,需要修改matplotlib的默认字体 通过matplotlib下的font_mange

    2023年04月09日
    浏览(79)
  • 使用R语言绘制折线图

    昨天我们分享了使用Python绘制折线图的教程,跟着NC学作图 | 使用python绘制折线图,考虑到很多同学基本不使用 Python 绘图。那么,我们也使用R语言复现此图形。 此外,在前期的教程中,我们基本没有分享过 折线图 的教程。因此,我们在这里也制作一期关于折线图的教程。在

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包