如何使 x 轴标签在 d3 中与 react 一起工作?
How to make x axis labels work in d3 with react?
这是我的代码示例:
import React, {Component} from 'react';
import {scaleOrdinal, axisBottom, select} from 'd3';
export default class BarChart extends Component {
constructor(props) {
super(props)
this.renderSvg = this.renderSvg.bind(this);
}
componentDidMount() {
this.renderSvg();
}
renderSvg() {
const margin = 20;
const width = 400;
const height = 800;
const data = ["why", "aren't", "you", "working"]
.map((title) => ({title}));
// create scalar for x axis
const x = scaleOrdinal()
.domain(data.map(({title}) => title))
.range([0, width]);
const xAxis = axisBottom(x);
// create svg and append graph
const svg = select("svg")
.attr("width", width)
.attr("height", height + margin)
.append("g")
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}
render() {
const {width, height, className} = this.props;
return <div className="body">
<svg className="svg" />
</div>
}
}
我已按照此站点上的示例进行操作:据我所知,https://bl.ocks.org/mbostock/3259783 非常接近,但我无法让它在预期的位置显示标签 regular/even 间隔。任何帮助将不胜感激,我是使用 d3 的新手。
问题是从 d3v3 到 d3v4/5 的转换。
d3.scale.ordinal()
(v3) 用于多种音阶类型,由您进行的 rangeX()
调用决定。
在 d3v5 中 d3.scaleOrdinal()
表示序数比例并将序数域映射到序数范围。 https://github.com/d3/d3-scale/#scaleOrdinal 您只将范围设置为 2 值数组。因此每个域值在 2 个范围值上交替。
这是一个 d3v5 示例。 运行 时,我调整了高度以看到一些东西。使用开发人员工具查看轴刻度的交替转换。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="body">
<svg class="svg"/>
</div>
<script>
function renderSvg() {
const margin = 20;
const width = 400;
const height = 100;
const data = ["why", "aren't", "you", "working"]
.map((title) => ({title}));
// create scalar for x axis
const x = d3.scaleOrdinal()
.domain(data.map(({title}) => title))
.range([0, width]);
const xAxis = d3.axisBottom(x);
// create svg and append graph
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height + margin)
.append("g");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}
renderSvg();
</script>
</body>
</html>
示例代码使用 .rangePoints([0, width])
并将 d3v5 转换为 d3.scalePoint()
。现在序数域被映射到一个连续的范围。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="body">
<svg class="svg"/>
</div>
<script>
function renderSvg() {
const margin = 20;
const width = 400;
const height = 100;
const data = ["why", "aren't", "you", "working"]
.map((title) => ({title}));
// create scalar for x axis
const x = d3.scalePoint()
.domain(data.map(({title}) => title))
.range([0, width]);
const xAxis = d3.axisBottom(x);
// create svg and append graph
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height + margin)
.append("g");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}
renderSvg();
</script>
</body>
</html>
这是我的代码示例:
import React, {Component} from 'react';
import {scaleOrdinal, axisBottom, select} from 'd3';
export default class BarChart extends Component {
constructor(props) {
super(props)
this.renderSvg = this.renderSvg.bind(this);
}
componentDidMount() {
this.renderSvg();
}
renderSvg() {
const margin = 20;
const width = 400;
const height = 800;
const data = ["why", "aren't", "you", "working"]
.map((title) => ({title}));
// create scalar for x axis
const x = scaleOrdinal()
.domain(data.map(({title}) => title))
.range([0, width]);
const xAxis = axisBottom(x);
// create svg and append graph
const svg = select("svg")
.attr("width", width)
.attr("height", height + margin)
.append("g")
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}
render() {
const {width, height, className} = this.props;
return <div className="body">
<svg className="svg" />
</div>
}
}
我已按照此站点上的示例进行操作:据我所知,https://bl.ocks.org/mbostock/3259783 非常接近,但我无法让它在预期的位置显示标签 regular/even 间隔。任何帮助将不胜感激,我是使用 d3 的新手。
问题是从 d3v3 到 d3v4/5 的转换。
d3.scale.ordinal()
(v3) 用于多种音阶类型,由您进行的 rangeX()
调用决定。
在 d3v5 中 d3.scaleOrdinal()
表示序数比例并将序数域映射到序数范围。 https://github.com/d3/d3-scale/#scaleOrdinal 您只将范围设置为 2 值数组。因此每个域值在 2 个范围值上交替。
这是一个 d3v5 示例。 运行 时,我调整了高度以看到一些东西。使用开发人员工具查看轴刻度的交替转换。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="body">
<svg class="svg"/>
</div>
<script>
function renderSvg() {
const margin = 20;
const width = 400;
const height = 100;
const data = ["why", "aren't", "you", "working"]
.map((title) => ({title}));
// create scalar for x axis
const x = d3.scaleOrdinal()
.domain(data.map(({title}) => title))
.range([0, width]);
const xAxis = d3.axisBottom(x);
// create svg and append graph
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height + margin)
.append("g");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}
renderSvg();
</script>
</body>
</html>
示例代码使用 .rangePoints([0, width])
并将 d3v5 转换为 d3.scalePoint()
。现在序数域被映射到一个连续的范围。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div class="body">
<svg class="svg"/>
</div>
<script>
function renderSvg() {
const margin = 20;
const width = 400;
const height = 100;
const data = ["why", "aren't", "you", "working"]
.map((title) => ({title}));
// create scalar for x axis
const x = d3.scalePoint()
.domain(data.map(({title}) => title))
.range([0, width]);
const xAxis = d3.axisBottom(x);
// create svg and append graph
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height + margin)
.append("g");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
}
renderSvg();
</script>
</body>
</html>