[英]D3 Dates not showing on X-axis
我試圖在圖表上繪制多條線。 我從繪制軸開始,x 軸具有 YYYY-MM-DD 格式的日期和 y 軸上的經驗分數。 但是由於某種原因,x 軸上的日期不顯示,這是為什么? 在將數據放入 d3.extent() 之前,是否需要進行一些格式化? 這是原始數據文件( https://raw.githubusercontent.com/QamarFarooq/data-for-testing/main/experience_scores.json )
import React, {Component, useRef, useEffect} from 'react';
import ExperienceScoresData from './experience_scores';
import * as d3 from "d3";
import { select, csv, selectAll} from 'd3';
import { extent, max, min } from "d3-array";
ExperienceScoresData.map(function(val){
val.customerExperienceScore *= 100;
return 0;
})
class Linechart extends Component {
constructor(props){
super(props)
this.createLineChart = this.createLineChart.bind(this)
}
metricToPercent (metric) {
return (metric / 2 + 0.5) * 100;
};
scoreToDescrip (score) {
if (score >= 0.6) {
return "Good";
} else if (score >= 0) {
return "Average";
} else {
return "Poor";
}
};
componentDidMount() {
this.createLineChart()
}
componentDidUpdate() {
this.createLineChart()
}
createLineChart() {
var margin = {top: 85, right: 60, bottom: 60, left: 80},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var node = this.node
var divObj = select(node)
var svgObj = divObj
.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 + ")");
//Read the data
d3.json("https://raw.githubusercontent.com/QamarFarooq/data-for-testing/main/experience_scores.json", function(data) {
// group the data: I want to draw one line per group
var sumstat = d3.nest() // nest function allows to group the calculation per level of a factor
.key(function(d) { return d.companyBusinessName;})
.entries(data);
//console.log(sumstat)
// Define the div for the tooltip
var tooltip = divObj
.append("div")
.attr("class","tooltip")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background-color", "white")
.style("box-shadow","0 0 4px #000000")
.style("padding", "10px")
const monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
var d = new Date();
tooltip.append("div")
.attr("class", "tooltipDate")
.html(monthNames[d.getMonth()] + " " + "(" + d.getFullYear() + ")")
.style("font-size", "20px")
.style("text-align","center")
tooltip.append("div")
.attr("class", "tooltipName")
.style("text-align","center")
.style("color","grey")
tooltip.append("div")
.attr("class", "tooltipTitle")
.style("text-align","center")
.html("Customer Sentiment")
.style("padding-top","10px")
tooltip.append("div")
.attr("class", "tooltipScore")
.style("text-align","center")
.style("color",'DarkGrey')
.style("font-size", "20px")
tooltip.append("div")
.attr("class", "tooltipPerception")
.style("text-align","center")
// Add title for linechart
svgObj.append("text")
.attr("text-anchor", "end")
.attr("font-size", 25)
.attr("x", 110)
.attr("y", -50)
.text("Customer Experience Score");
// Add X axis --> it is a date format
var x = d3.scaleLinear()
.domain(d3.extent(data, function(d) { return d.companyReviewDate; }))
.range([ 0, width ]);
svgObj.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("stroke-width","0.3")
.style("opacity","0.5")
.call(d3.axisBottom(x).tickSize(-height).tickFormat('').ticks(5))
// ticks
svgObj.append("g")
.style("opacity","0.7")
.style("font", "14px times")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(5));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.customerExperienceScore; })])
.range([ height, 0 ]);
svgObj.append("g")
.attr("stroke-width","0.3")
.style("opacity","0.5")
.call(d3.axisLeft(y).tickSize(-width).tickFormat('').ticks(5))
// ticks
svgObj.append("g")
.style("opacity","0.7")
.style("font", "14px times")
.call(d3.axisLeft(y).ticks(5));
// Add X axis label:
svgObj.append("text")
.attr("text-anchor", "end")
.attr("font-size", 20)
.attr("x", width/2 + margin.left)
.attr("y", height + 50)
.style("fill", d3.color("grey"))
.text("Year Of Birth");
// Add Y axis label:
svgObj.append("text")
.attr("text-anchor", "end")
.attr("font-size", 20)
.attr("transform", "rotate(-90)")
.attr("x", -height/2 + 40)
.attr("y", -margin.left + 25)
.style("fill", d3.color("grey"))
.text("N-Value")
// color palette
var key = sumstat.map(function(d){ return d.key }) // list of group names
var color = d3.scaleOrdinal()
.domain(key)
.range(['#e41a1c','#377eb8','#4daf4a'])
// Add one DOT in the legend for each name.
svgObj.selectAll(".dots")
.data(key)
.enter()
.append("circle")
.attr("cx", function(d,i){ return 250 + i*120})
.attr("cy", -30)
.attr("r", 7)
.style("fill", function(d){ return color(d)})
// Add LABEL for legends of each dot.
svgObj.selectAll(".labels")
.data(key)
.enter()
.append("text")
.style("fill", d3.color("grey"))
.attr("x", function(d,i){ return 270 + i*120})
.attr("y", -28)
.text(function(d){ return d})
.attr("text-anchor", "left")
.style("alignment-baseline", "middle")
})
}
render() {
return <div ref={node => this.node = node} className="example_div"> </div>
}
}
export default Linechart;
如果data.companyReviewDate
是一個日期,但您從 JSON 中獲取它,則首先需要對其進行解析,以便將其識別為日期。 否則,它只是一個字符串 - 而scaleLinear
不能很好地處理字符串。 因此,要獲取它,請使用
data.forEach(function(d) {
d.companyReviewDate = new Date(d.companyReviewDate);
});
然后, scaleLinear
只考慮數字,而不是日期。 這意味着即使它與 Dates 一起工作,它也會看到自 01-01-1970 以來的毫秒數,這對用戶來說不是很友好。 使用scaleTime()
代替!
var divObj = d3.select(".example_div") var margin = { top: 85, right: 60, bottom: 60, left: 80 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var svgObj = divObj .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 + ")"); //Read the data d3.json("https://raw.githubusercontent.com/QamarFarooq/data-for-testing/main/experience_scores.json", function(data) { // Transform `companyReviewDate` into an actual date data.forEach(function(d) { d.companyReviewDate = new Date(d.companyReviewDate); }); // group the data: I want to draw one line per group var sumstat = d3.nest() // nest function allows to group the calculation per level of a factor .key(function(d) { return d.companyBusinessName; }) .entries(data); console.log(sumstat) // Add title for linechart svgObj.append("text") .attr("text-anchor", "end") .attr("font-size", 25) .attr("x", 110) .attr("y", -50) .text("Customer Experience Score"); // Add X axis --> it is a date format var x = d3.scaleTime() .domain(d3.extent(data, function(d) { return d.companyReviewDate; })) .range([0, width]); svgObj.append("g") .attr("transform", "translate(0," + height + ")") .attr("stroke-width", "0.3") .style("opacity", "0.5") .call(d3.axisBottom(x).tickSize(-height).tickFormat('').ticks(5)) // ticks svgObj.append("g") .style("opacity", "0.7") .style("font", "14px times") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).ticks(5)); // Add Y axis var y = d3.scaleLinear() .domain([0, d3.max(data, function(d) { return +d.customerExperienceScore; })]) .range([height, 0]); svgObj.append("g") .attr("stroke-width", "0.3") .style("opacity", "0.5") .call(d3.axisLeft(y).tickSize(-width).tickFormat('').ticks(5)) // ticks svgObj.append("g") .style("opacity", "0.7") .style("font", "14px times") .call(d3.axisLeft(y).ticks(5)); // Add X axis label: svgObj.append("text") .attr("text-anchor", "end") .attr("font-size", 20) .attr("x", width / 2 + margin.left) .attr("y", height + 50) .style("fill", d3.color("grey")) .text("Year Of Birth"); // Add Y axis label: svgObj.append("text") .attr("text-anchor", "end") .attr("font-size", 20) .attr("transform", "rotate(-90)") .attr("x", -height / 2 + 40) .attr("y", -margin.left + 25) .style("fill", d3.color("grey")) .text("N-Value") });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script> <div class="example_div"></div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.