带有时间刻度的 js d3 图表

飞碟

我是一个编码 js 和 d3 的新手,我有下面的代码,我想在 x 轴上显示数组中的日期而不是数字。我尝试了很多方法来显示日期;大多数方法在 HTML 控制台中显示没有行的日期和有错误的数据,它无法读取它只允许数字的日期的数据类型。

<!DOCTYPE html>
<meta charset="utf-8">



<body>
</body>

<!-- Load in the d3 library -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>

// 2. Use the margin convention practice 
var margin = {top: 200, right: 300, bottom: 400, left: 300}
  , width = window.innerWidth - margin.left - margin.right // Use the window's width 
  , height = window.innerHeight - margin.top - margin.bottom; // Use the window's height


var parseDate = d3.timeParse("%Y-%m-%d");

// 8. An array of objects of length N. Each object has key -> value pair, the key being "y" and the value is a random number
var xdata = [
    ["2021-08-01",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-02",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-03",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-04",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-05",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-06",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-07",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-08",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-09",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-10",(d3.randomUniform(100)()).toFixed(1)],
    ["2021-08-11",(d3.randomUniform(100)()).toFixed(1)]
];



var n = xdata.length;
var max_value = 0;
var col1 = 0;
for (let i = 0; i < n; i++) {
xdata[i][0] = parseDate(xdata[i][0]);
//console.log(xdata[i][0]);
col1 = parseFloat(xdata[i][1])
if (col1 > max_value)
    max_value = col1


}
console.log(max_value);


// 5. X scale will use the index of our data
var xScale = d3.scaleLinear()
  .domain([0,n-1 ]) // input
    .range([0, width]); // output


// 6. Y scale will use the randomly generate number 
var yScale = d3.scaleLinear()
    .domain([0, max_value]) // input 
    .range([height, max_value]); // output 

// 7. d3's line generator
var line = d3.line()
    .x(function(d, i) { return xScale(i); }) // set the x values for the line generator
    .y(function(d) { return yScale(d.y); }) // set the y values for the line generator 
    .curve(d3.curveMonotoneX) // apply smoothing to the line



//var dataset = d3.range(n).map(function(d) { return {"y": (d3.randomUniform(100)()).toFixed(1) } })

var dataset = xdata.map(function(d) {
      return {
         x: parseDate(d[0]),
         y: d[1]
      };
      
  });

// 1. Add the SVG to the page and employ #2
var svg = d3.select("body").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 + ")");

// 3. Call the x axis in a group tag
svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

// 4. Call the y axis in a group tag
svg.append("g")
    .attr("class", "y axis")
    .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft

// 9. Append the path, bind the data, and call the line generator 
svg.append("path")
    .datum(dataset) // 10. Binds data to the line 
    .attr("fill", "none")
    .attr("stroke", "steelblue")
    .attr("stroke-width", 3)
    .attr("d", line); // 11. Calls the line generator 

// 12. Appends a circle for each datapoint 
svg.selectAll(".dot")
    .data(dataset)
  .enter().append("circle") // Uses the enter().append() method
    .style("fill","steelblue")
    .attr("cx", function(d, i) { return xScale(i) })
    .attr("cy", function(d) { return yScale(d.y) })
    .attr("r", 5);

// 13. Appends data text to each datapoint  
svg.selectAll(".text")
    .data(dataset)
    .enter().append("text")
    .style("fill", "red") 
    .attr("x", function(d, i) { return xScale(i) - 5 })
    .attr("y", function(d) { return yScale(d.y) - 20 })
    .text(function(d) { return d.y });
    

</script>

感谢您提前回答

我建议立即将字符串解析为 Date 对象,然后d3.scaleTime用于 x 比例。下面是一个例子。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://d3js.org/d3.v7.js"></script>
</head>

<body>
    <div id="chart"></div>

    <script>
      // set up

      const margin = { top: 40, bottom: 40, left: 40, right: 40 };

      const width = 500 - margin.left - margin.right;
      const height = 250 - margin.top - margin.bottom;

      const svg = d3.select('#chart')
        .append('svg')
          .attr('width', width + margin.left + margin.right)
          .attr('height', height + margin.top + margin.bottom);

      const g = svg.append('g')
          .attr('transform', `translate(${margin.left},${margin.top})`);

      // data

      const parseDate = d3.timeParse("%Y-%m-%d");

      const dataset = [
        ["2021-08-01",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-02",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-03",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-04",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-05",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-06",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-07",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-08",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-09",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-10",(d3.randomUniform(100)()).toFixed(1)],
        ["2021-08-11",(d3.randomUniform(100)()).toFixed(1)]
      ].map(d => ({ date: parseDate(d[0]), value: parseFloat(d[1]) }));

      const minMaxDate = d3.extent(dataset, d => d.date);
      const maxValue = d3.max(dataset, d => d.value);

      // scales

      const x = d3.scaleTime()
          .domain(minMaxDate)
          .range([0, width]);

      const y = d3.scaleLinear()
          .domain([0, maxValue])
          .range([height, 0]);

      // line generator

      const line = d3.line()
          .x(d => x(d.date))
          .y(d => y(d.value))
          .curve(d3.curveMonotoneX);


      // axes

      g.append("g")
          .attr("class", "x axis")
          .attr("transform", `translate(0,${height})`)
          .call(d3.axisBottom(x));
      
      g.append("g")
          .attr("class", "y axis")
          .call(d3.axisLeft(y));


      // line

      g.append('path')
          .datum(dataset)
          .attr('fill', 'none')
          .attr('stroke', 'steelblue')
          .attr('stroke-width', 3)
          .attr('d', line);

      // circles

      g.selectAll('.dot')
        .data(dataset)
        .join('circle')
          .attr('fill', 'steelblue')
          .attr('cx', d => x(d.date))
          .attr('cy', d => y(d.value))
          .attr('r', 5);

      // text labels

      g.selectAll('.text')
        .data(dataset)
        .join('text')
          .attr('fill', 'red')
          .attr('x', d => x(d.date) - 5)
          .attr('y', d => y(d.value) - 20)
          .text(d => d.value);
    </script>
</body>
</html>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

当我想创建带有时间刻度的图表时,如何在RequireJS中正确包含Moment.js和Chart.js?

创建带有时间变量的图表

D3 - 创建一个带有 3 个固定 y 轴刻度的图表

来自SQL数据库的带有时间的JFreechart图表

C3.js-具有时间的时间序列无法解析

为什么在 Chart.js 中放置两个带有时间笛卡尔轴的数据集会导致两个 Y 轴刻度集?

D3 图表曲线在刻度标签中有错误的数据

JS d3 缩放时间不会产生正确的刻度

D3图表-组合多个图表

我们可以在 OBIEE 中创建带有时间线的动态信息图表吗?

D3 js可折叠图表增加了圆弧曲线的半径

如何使用D3 Js向下钻取以创建图表列

在D3 JS中将div放置在图表的左上角

如何获得不重叠的圆形包装D3 JS图表?

AngularJS:链接函数中带有D3图表的指令仅工作一次

如何将带有工具提示的圆添加到d3图表

使用D3创建带有线的交互式图表(缩放/平移)

带有 D3 图表的 React 组件渲染次数过多

带有 2 行的 D3js 图表 - 仅显示行

带有Chart js的日期和时间图表

FullCalendar.js:渲染带有时间标签的背景吗?

多系列d3 svg图表未显示刻度线

更改d3图表的轴线的粗细/宽度,而不影响刻度标签

严格动画需要 D3.js API 的哪些部分(即没有图表、没有绘图、没有图表等)?

给定d3中有1个文件馈送的1个图表+要绘制给定的X文件+ d3数组,则要绘制X个图表

D3.js - 如何使用内联 JSON 作为 D3 图表的数据集,而不是 csv/tsv/json 文件

D3.JS 图表未显示

具有嵌套JSON数据的C3,D3图表

SVG中的路径位于D3图表中圆圈的前面,尽管有附加顺序