Javascript Reactsj和d3v4集成——带有jest测试的表格和饼图应用程序
我试图创建一个react、d3和jest测试的基本集成示例。我已经创建了一个饼图和表格组件——我非常希望将数据从主应用程序推送到表格和饼图组件中。只有当用户单击表时,才会填充饼图 --沙箱 -我想出了这个例子 6月9日——目前的一体化 数据看起来有点像这样Javascript Reactsj和d3v4集成——带有jest测试的表格和饼图应用程序,javascript,reactjs,d3.js,jestjs,Javascript,Reactjs,D3.js,Jestjs,我试图创建一个react、d3和jest测试的基本集成示例。我已经创建了一个饼图和表格组件——我非常希望将数据从主应用程序推送到表格和饼图组件中。只有当用户单击表时,才会填充饼图 --沙箱 -我想出了这个例子 6月9日——目前的一体化 数据看起来有点像这样 [ { "Country": "Afghanistan", "TotalConfirmed": 20917, "TotalDeaths": 369, "TotalRecovered"
[
{
"Country": "Afghanistan",
"TotalConfirmed": 20917,
"TotalDeaths": 369,
"TotalRecovered": 2171,
},
{
"Country": "Albania",
"TotalConfirmed": 1263,
"TotalDeaths": 34,
"TotalRecovered": 945,
},
{
"Country": "Algeria",
"TotalConfirmed": 10265,
"TotalDeaths": 715,
"TotalRecovered": 6799,
}
]
- 我在重新分析道具中的数据时遇到问题。我将不得不将饼图数据重构为标签、值格式——但我也不确定这方面的jest测试
import React from 'react';
import Pie from './Pie/Pie';
import Table from './Table/Table';
import './App.css';
class App extends React.Component {
componentDidMount() {
//get data
}
render() {
const data = [
{
"Country": "Afghanistan",
"TotalConfirmed": 20917,
"TotalDeaths": 369,
"TotalRecovered": 2171,
},
{
"Country": "Albania",
"TotalConfirmed": 1263,
"TotalDeaths": 34,
"TotalRecovered": 945,
},
{
"Country": "Algeria",
"TotalConfirmed": 10265,
"TotalDeaths": 715,
"TotalRecovered": 6799,
}
];
const piedata =[
{
label: 'Jam',
value: 50,
},
{
label: 'Coconut',
value: 10,
},
{
label: 'Nutmeg',
value: 20,
},
{
label: 'Tumeric',
value: 20,
},
];
return (
<div className="App">
<div className="row">
<div className="col col-6">
<Table data={data} />
</div>
<div className="col col-6">
<Pie
data={piedata}
width="300"
height="300"
r="110"
ir="0"
/>
</div>
</div>
</div>
);
}
}
export default App;
从“React”导入React;
从“./Pie/Pie”导入饼图;
从“./Table/Table”导入表;
导入“/App.css”;
类应用程序扩展了React.Component{
componentDidMount(){
//获取数据
}
render(){
常数数据=[
{
“国家”:“阿富汗”,
“已确认总数”:20917,
“死亡总数”:369人,
“恢复总数”:2171,
},
{
“国家”:“阿尔巴尼亚”,
“已确认总数”:1263,
“死亡总数”:34,
“恢复总数”:945,
},
{
“国家”:“阿尔及利亚”,
“已确认总数”:10265,
“死亡总数”:715人,
“恢复总数”:6799,
}
];
常数piedata=[
{
标签:“果酱”,
价值:50,
},
{
标签:'椰子',
数值:10,
},
{
标签:“肉豆蔻”,
价值:20,
},
{
标签:“Tumeric”,
价值:20,
},
];
返回(
);
}
}
导出默认应用程序;
//Pie.js
import React from 'react';
import * as d3 from "d3";
import ReactDOM from 'react-dom';
import $ from 'jquery';
import './Pie.css';
class Pie extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
var $this = $(this.myRef.current);
const data = this.props.data;
const width = parseInt(this.props.width,10),
height = parseInt(this.props.height,10),
radius = parseInt(this.props.r,10),
innerradius = parseInt(this.props.ir,10);
var color = d3.scaleOrdinal().range(["#f0cf85", "#e7f0c3", "#a4d4ae", "#32afa9"]);
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(innerradius);
data.forEach(function(d) {
d.total = +d.value;
});
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.total; });
var svg = d3.select($this[0])
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr('class', 'piechart')
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var segments = svg.append('g').attr('class', 'segments');
var slices = segments.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
slices.append("path")
.attr("d", arc)
.attr('fill', function(d, i) {
return color(i);
})
}
render() {
return (
<div
ref={this.myRef}
className="Pie"
/>
);
}
}
export default Pie;
从“React”导入React;
从“d3”导入*作为d3;
从“react dom”导入react dom;
从“jquery”导入美元;
导入“/Pie.css”;
类扩展了React.Component{
建造师(道具){
超级(道具);
this.myRef=React.createRef();
}
componentDidMount(){
var$this=$(this.myRef.current);
const data=this.props.data;
const width=parseInt(this.props.width,10),
高度=parseInt(此.props.height,10),
半径=parseInt(这个.props.r,10),
innerradius=parseInt(this.props.ir,10);
var color=d3.scaleOrdinal().range([“f0cf85”、“e7f0c3”、“a4d4ae”、“32afa9”);
var arc=d3.arc()
.外层(半径-10)
.内半径(内半径);
data.forEach(函数(d){
d、 总计=+d.值;
});
var pie=d3.pie()
.sort(空)
.value(函数(d){返回d.total;});
var svg=d3.select($this[0])
.append(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.附加(“g”)
.attr('class','piechart')
.attr(“变换”、“平移”(+width/2+)、“+height/2+”);
var segments=svg.append('g').attr('class','segments');
变量切片=分段。选择全部(“.arc”)
.数据(pie(数据))
.enter().append(“g”)
.attr(“类”、“弧”);
附加(“路径”)
.attr(“d”,弧)
.attr('fill',函数(d,i){
返回颜色(i);
})
}
render(){
返回(
);
}
}
导出默认饼图;
//Table.js
import React from 'react';
import ReactDOM from 'react-dom';
import $ from 'jquery';
import './Table.css';
class Table extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
var $this = $(this.myRef.current);
}
rows(data) {
return (data.map((listValue, index) => {
return (
<tr key={index}>
<td>{listValue.Country}</td>
<td>{listValue.TotalConfirmed}</td>
<td>{listValue.TotalDeaths}</td>
<td>{listValue.TotalRecovered}</td>
</tr>
);
}));
}
render() {
return (
<div
ref={this.myRef}
className="Table"
>
<table>
<thead>
<tr>
{Object.keys(this.props.data[0]).map((key, index) => {
return (<th key={index}>{key}</th>);
})}
</tr>
</thead>
<tbody>
{this.rows(this.props.data)}
</tbody>
</table>
</div>
);
}
}
export default Table;
从“React”导入React;
从“react dom”导入react dom;
从“jquery”导入美元;
导入“/Table.css”;
类表扩展了React.Component{
建造师(道具){
超级(道具);
this.myRef=React.createRef();
}
componentDidMount(){
var$this=$(this.myRef.current);
}
行(数据){
return(data.map)((listValue,index)=>{
返回(
{listValue.Country}
{listValue.totalconfirm}
{listValue.TotalDeathers}
{listValue.TotalRecovered}
);
}));
}
render(){
返回(
{Object.keys(this.props.data[0]).map((key,index)=>{
返回({key});
})}
{this.rows(this.props.data)}
);
}
}
导出默认表;
这些测试正确吗 App.test.js
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
import Table from './Table/Table';
import Pie from './Pie/Pie';
import allData from './data.json';
fetch = jest.fn().mockImplementation(() => {
const data = allData;
data.json = jest.fn().mockImplementation(() => Promise.resolve(data));
return Promise.resolve(data);
});
describe('App', () => {
const wrapper = shallow(<App />);
it('initial render', () => {
expect(wrapper.find(Table).prop('cols')).toHaveLength(4);
expect(wrapper.find(Pie).prop('data')).toEqual([
{
label: '',
value: 100,
},
]);
});
it('should update pie data when row is selected', () => {
const row = wrapper.state('data')[0];
const pieDataRefactor = wrapper.instance().pieDataRefactor(row);
console.log(pieDataRefactor);
wrapper.instance().rowSelected(row);
expect(wrapper.find(Pie).prop('data')).toEqual(pieDataRefactor);
});
});
从“React”导入React;
从“酶”导入{shall};
从“./App”导入应用程序;
从“./Table/Table”导入表;
从“./Pie/Pie”导入饼图;
从“/data.json”导入所有数据;
fetch=jest.fn().mockImplementation(()=>{
常量数据=所有数据;
data.json=jest.fn().mockImplementation(()=>Promise.resolve(data));
返回承诺。解析(数据);
});
描述('App',()=>{
常量包装器=浅();
它('初始渲染',()=>{
expect(wrapper.find(Table.prop('cols')).toHaveLength(4);
expect(wrapper.find(Pie.prop('data')).toEqual([
{
标签:“”,
数值:100,
},
]);
});
它('选择行时应更新饼图数据',()=>{
const row=wrapper.state('data')[0];
const pieDataRefactor=wrapper.instance().pieDataRefactor(行);
log(pieDataRefactor);
wrapper.instance().rowSelected(行);
import React from 'react';
import Table from './Table';
import allData from '../data.json';
import { shallow } from 'enzyme';
const columns = [
'Country',
'CountryCode',
'Slug',
'NewConfirmed',
'TotalConfirmed',
'NewDeaths',
'TotalDeaths',
'NewRecovered',
'TotalRecovered',
'Date',
];
describe('Table', () => {
const defaultProps = {
cols: columns,
data: allData.Countries,
rowSelected: jest.fn(),
};
const wrapper = shallow(<Table {...defaultProps} />);
it('should render table', () => {
expect(wrapper.find('.Table th')).toHaveLength(10);
expect(wrapper.find('.Table tbody tr')).toHaveLength(allData.Countries.length);
});
it('should call rowSelected', () => {
const row = wrapper.find('.Table tbody tr').at(0);
row.simulate('click');
expect(defaultProps.rowSelected).toHaveBeenCalled();
expect(defaultProps.rowSelected).toHaveBeenCalledWith(allData.Countries[0]);
});
});
import React from 'react';
import Pie from './Pie';
import $ from 'jquery';
import * as d3 from 'd3';
import { mount } from 'enzyme';
describe('Pie', () => {
const defaultProps = {
data: [
{ label: 'TotalConfirmed', value: 20917 },
{ label: 'TotalDeaths', value: 369 },
{ label: 'TotalRecovered', value: 2171 },
],
height: 200,
width: 200,
r: 30,
ir: 10,
};
// const wrapper = mount(<Pie {...defaultProps} />);
it('should render Pie', () => {
const arcSpy = jest.spyOn(d3, 'arc');
const selectSpy = jest.spyOn(d3, 'select');
const scaleOrdinalSpy = jest.spyOn(d3, 'scaleOrdinal');
const pieSpy = jest.spyOn(d3, 'pie');
const wrapper = mount(<Pie {...defaultProps} />);
expect(wrapper.find('.Pie')).toHaveLength(1);
expect(arcSpy).toHaveBeenCalled();
expect(pieSpy).toHaveBeenCalled();
expect(selectSpy).toHaveBeenCalled();
expect(scaleOrdinalSpy).toHaveBeenCalled();
});
});