D3(v5) in TypeScript 坐标轴之 scaleBand用法

在学习d3时候,发现在TS中实现D3的坐标轴中遇到一些错误,而这些错误却不会存在于js(因为ts的类型检查)写法中,因此做下笔记:

import * as d3 from 'd3';
import * as React from 'react';

class TestGraph extends React.Component {
public componentDidMount() {
const marge = {
top: 60,
bottom: 60,
left: 60,
right: 60
};
const dataSet: any[] = [10, 20, 30, 23, 13, 40, 27, 35, 20];
const svg = d3.select("svg");
const g = svg.append("g")
.attr("transform", `translate(${marge.top},${marge.left})`);
const width: any = svg.attr('width');
const height: any = svg.attr('height');
// 此处必须把.domain里的参数转为字符串数组,不然会报类型错
const xScale = d3.scaleBand()
.domain(d3.range(dataSet.length).map(value => {
return value.toString();
}))
.rangeRound([0, width - marge.left - marge.right]);
const xAxis = d3.axisBottom(xScale);

const yScale = d3.scaleLinear()
.domain([0, d3.max(dataSet)])
.range([height - marge.top - marge.bottom, 0]);
const yAxis = d3.axisLeft(yScale);

const gs = g.selectAll(".rect")
.data(dataSet)
.enter()
.append("g");
const rectPadding = 20;// 矩形之间的间隙
const rectWidth = xScale.step();
gs.append("rect")
.attr("x", (d, i) => {
// 此处不能用xScale(i),因为参数只能接受string,就算使用i.toString(),也会报错此对象有可能为undefined
return xScale.step() * (i + xScale.paddingOuter()) + rectPadding / 2;
})
.attr("y", d => {
return yScale(d);
})
.attr("width", rectWidth - rectPadding)
.attr("height", d => {
return height - marge.top - marge.bottom - yScale(d);
})
.attr("fill", "blue");

const fontSize = 14;
gs.append("text")
.attr("x", (d, i) => {
return xScale.step() * (i + xScale.paddingOuter()) + rectPadding / 2;
})
.attr("y", d => {
return yScale(d);
})
.attr("dx", (xScale.step() - rectPadding) / 2 - fontSize / 2)
.attr("dy", 20)
.attr("font-size", fontSize)
.text(d => {
return d;
});

g.append("g")
.attr("transform", `translate(0,0)`)
.call(yAxis);
g.append("g")
.attr("transform", `translate(0,${yScale(0)})`)
.call(xAxis);
}

public render() {
return (
<svg width={960} height={600}/>
)
}
}

export default TestGraph;

效果如下:

posted @ 2018-07-27 11:10  Cober_kuang  阅读(3005)  评论(0编辑  收藏  举报