问题描述
我对反应还很陌生,但对玩笑也完全陌生。我正在测试其他人已经开发的 recharts Linechart(我知道,与真正的 TDD 相反)。我正在寻找一种使用以下图表代码的方法。我想要做的是模拟数据存储(来自 mainApiResponseReducer)并将其用作数据部分的驱动程序,我还想测试 rechart 的组件和此代码(按钮组件、折线图渲染和工具提示渲染)并有正确的数据,但现在可以跳过 X 轴和 Y 轴和线,最大的问题是图表渲染与数据和工具提示)。最好的方法是什么?考虑到我几乎不知道该去哪里,任何开始的示例代码都值得赞赏:) 谢谢。代码如下:
import React,{ useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { usedispatch,useSelector } from 'react-redux';
import {
LineChart,Line,XAxis,YAxis,Cartesiangrid,Tooltip,ReferenceLine,ResponsiveContainer
} from 'recharts';
import { object } from 'prop-types';
import styles from '../styles.scss';
const useStyles = makeStyles((theme) => ({
buttonOff: {
width: '75px',height: '24px',borderRadius: '50px',margin: '2.5px',color: 'rgba(8,8,59,1)',BoxShadow: ' 0px 0px 0px 0px rgba(8,borderStyle: 'solid',backgroundColor: 'rgba(8,0.1)',opacity: '0.3'
},buttonRed: {
width: '75px',borderColor: '#CD2821',color: '#BE1710',backgroundColor: '#FAE9E8'
},buttonGreen: {
width: '75px',borderColor: '#288179',color: '#22766F',backgroundColor: '#E9F2F1'
},buttonBlue: {
width: '75px',borderColor: '#0E65BC',color: '#0E65BC',backgroundColor: '#E7F1FA'
}
}));
const CustomTooltip = (props) => {
const {
active,label,payload,temp2
} = props;
if (active && payload && payload.length) {
return (
<div style={{
backgroundColor: '#16214F',width: '160px',height: '90px',left: '80px',position: 'relative'
}}
>
{typeof payload[0] !== 'undefined'
&& <p style={{ color: '#FFFFFF',paddingTop: '0px',fontSize: '15px' }}>{payload[0].payload.fsc_YR_NBR} - WEEK {payload[0].payload.week_NBR}</p>}
{typeof payload[2] !== 'undefined'
&& (
<div style={{ color: '#FFFFFF',display: 'inline',marginRight: '20px' }}><button style={{
backgroundColor: payload[2].stroke,width: '25px',height: '7px',borderRadius: '50px'
}} disabled
/>{` ${payload[2].value.toFixed(2)} `}
</div>
) }
{typeof payload[1] !== 'undefined'
&& (
<div style={{ color: '#FFFFFF',display: 'inline' }}><button style={{
backgroundColor: payload[1].stroke,borderRadius: '50px'
}} disabled
/>{` ${payload[1].value.toFixed(2)}`}
</div>
) }
{typeof payload[0] !== 'undefined'
&& (
<div style={{ color: '#FFFFFF' }}><button style={{
backgroundColor: payload[0].stroke,borderRadius: '50px'
}} disabled
/>{` ${payload[0].value.toFixed(2)}`}
</div>
) }
</div>
);
}
return null;
};
const ForecastGraph = () => {
const dispatch = usedispatch();
const mainApiResponse = useSelector((state) => state.mainApiResponseReducer);
const temp2 = [];
let i; let
t1 = 1; let pos;
let max = 10;
temp2.push({ week: 0 });
const data = [];
if (mainApiResponse.data) {
if (mainApiResponse.data[0]) var flag = mainApiResponse.data[0].fsc_WK_NBR;
for (let c = 0; c < mainApiResponse.data.length; c++) {
if (flag === mainApiResponse.data[c].fsc_WK_NBR) data.push(mainApiResponse.data[c]);
else {
data.push({ fsc_WK_NBR: flag }); c--;
}
if (flag == 52) flag = 0;
flag++;
}
// console.log('d');
// console.log(data);
for (i = 0; i < data.length; i++) {
if (Object.keys(data[i]).length > 3) {
pos = i;
break;
}
pos = data.length;
}
if (data[i - 1]) {
console.log(data[i - 1].fsc_YR_NBR);
var cp = 52 * (mainApiResponse.year - data[i - 1].fsc_YR_NBR) + (mainApiResponse.week - data[i - 1].fsc_WK_NBR);
console.log(`cp= + ${cp}`);
const wk = data[i - 1].fsc_WK_NBR;
}
console.log(pos);
if ((pos + cp) < 156) {
for (var j = 0; j < (156 - pos); j++) {
temp2.push({ fsc_WK_NBR: t1 });
t1++;
if (t1 > 52) t1 = 1;
}
pos = 156;
}
i = 0;
console.log('a');
console.log(temp2);
let m = 0;
for (m = (pos + cp - 156); m < data.length; m++) {
if (t1 > 52) { t1 = 1; }
if (Object.keys(data[m]).length == 3) {
temp2.push({
fsc_WK_NBR: t1,week_NBR: data[m].fsc_WK_NBR,fsc_YR_NBR: data[m].fsc_YR_NBR,sales_UNITS: data[m].sales_UNITS
});
t1++;
if (max < data[m].sales_UNITS) { max = data[m].sales_UNITS; }
} else if (Object.keys(data[m]).length > 3) break;
else { temp2.push({ fsc_WK_NBR: t1 }); t1++; }
}
for (let q = 0; q < cp - 1; q++) {
if (t1 > 52) { t1 = 1; }
temp2.push({ fsc_WK_NBR: t1 });
t1++;
m++;
}
for (var j = m; j < data.length; j++) {
if (t1 > 52) { t1 = 1; }i++;
if (Object.keys(data[j]).length == 4) {
temp2.push({
fsc_WK_NBR: t1,week_NBR: data[j].fsc_WK_NBR,fsc_YR_NBR: data[j].fsc_YR_NBR,forecast_UNITS_BY: data[j].forecast_UNITS_BY,forecast_UNITS_LIFT: data[j].forecast_UNITS_LIFT
});
t1++;
if (max < data[j].forecast_UNITS_BY) { max = data[j].forecast_UNITS_BY; }
} else { temp2.push({ fsc_WK_NBR: t1 }); t1++; }
}
for (let k = i; k < 52; k++) {
if (t1 > 52) { t1 = 1; }
temp2.push({ fsc_WK_NBR: t1 });
t1++;
}
}
console.log('final');
console.log(temp2);
const classes = useStyles();
const [on1,setButton1] = useState(true);
const [on2,setButton2] = useState(true);
const [on3,setButton3] = useState(true);
const handlebutton1 = () => {
setButton1(!on1);
};
const handlebutton2 = () => {
setButton2(!on2);
};
const handlebutton3 = () => {
setButton3(!on3);
};
const formatXAxis = (tickItems) => (tickItems / 13) * 3;
return (
<div className={ styles.graphGrid }>
<center>
{on1
&& <button className={ classes.buttonRed } onClick={ handlebutton1 }>Sales</button>
}
{!on1
&& (
<button className={ classes.buttonOff }
onClick={ handlebutton1 }
>Sales
</button>
)
}
{on2
&& <button className={ classes.buttonGreen } onClick={ handlebutton2 }>B2</button>
}
{!on2
&& (
<button className={ classes.buttonOff }
onClick={ handlebutton2 }
>BYD
</button>
)
}
{on3
&& <button className={ classes.buttonBlue } onClick={ handlebutton3 }>B3</button>
}
{!on3
&& (
<button className={ classes.buttonOff }
onClick={ handlebutton3 }
>Lowe's
</button>
)
}
<ResponsiveContainer height="50%" width="99%" aspect={ 4 }>
<LineChart
width={ 500 }
height={ 300 }
data={ temp2 }
margin={{
top: 15,right: 30,left: 20,bottom: 5
}}
>
<Cartesiangrid vertical={ false } opacity="0.4" />
<XAxis
dataKey="fsc_WK_NBR"
xAxisId={ 0 }
tickFormatter={ formatXAxis }
interval={ 12 }
tickLine
tickMargin={ 5 } />
<YAxis
type="number"
domain={ [0,max] }
tickCount={ 7 }
axisLine={ false }
tickLine={ false } />
<Tooltip
offset="1"
content={ <CustomTooltip temp2={ temp2 } /> } />
<ReferenceLine x={ 52 } />
<ReferenceLine x={ 104 } />
<ReferenceLine x={ 156 } stroke="black" />
{on1 && temp2.length
&& <Line type="monotone" dataKey="sales_UNITS" stroke="red" isAnimationActive={ false } dot={{ r: 0 }} />// red
}
{on2 && temp2.length
&& <Line type="monotone" dataKey="forecast_UNITS_BY" stroke="green" isAnimationActive={ false } dot={{ r: 0 }} /> // green
}
{on3 && temp2.length
&& <Line type="monotone" dataKey="forecast_UNITS_LIFT" stroke="blue" isAnimationActive={ false } dot={{ r: 0 }} /> // blue
}
</LineChart>
</ResponsiveContainer>
</center>
</div>
);
};
export default ForecastGraph;
我只是想开始看看我是否可以渲染这个 ForecastGraph 组件。下面是我的代码,但我收到以下错误,并且不确定如何处理元素类型:
ForecastGraph.test.jsx:
/**
* @jest-environment jsdom
*/
import React from 'react';
import { mount } from 'enzyme';
import {ForecastGraph} from '../../../src/common/components/common/ForecastTab/ForecastGraph';
describe('ForecastGraph/>',() => {
let wrapper;
// const data = [
// {fsc_WK_NBR: 11,fsc_YR_NBR: 2021,sales_UNITS: 160},// {fsc_WK_NBR: 12,sales_UNITS: 203},// {fsc_WK_NBR: 13,sales_UNITS: 172},// {fsc_WK_NBR: 14,sales_UNITS: 170},// {fsc_WK_NBR: 15,sales_UNITS: 249},// {fsc_WK_NBR: 16,sales_UNITS: 166},// {fsc_WK_NBR: 17,sales_UNITS: 108},// {fsc_WK_NBR: 18,sales_UNITS: 207},// {fsc_WK_NBR: 19,forecast_UNITS_BY: 153,forecast_UNITS_LIFT:190}
// ];
it('rendering ForecastGraph Component',() => {
wrapper = mount(<ForecastGraph/>).toJSON();
expect(wrapper).toMatchSnapshot();
});
});
测试失败控制台日志:
FAIL tests/components/ForecastGraph/ForecastGraph.test.jsx
ForecastGraph/>
× rendering ForecastGraph Component (138ms)
● ForecastGraph/> › rendering ForecastGraph Component
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in,or you might have mixed up default and named imports.
Check the render method of `WrapperComponent`.
25 |
26 | it('rendering ForecastGraph Component',() => {
> 27 | wrapper = mount(<ForecastGraph/>).toJSON();
| ^
28 | expect(wrapper).toMatchSnapshot();
29 | });
30 | });
at createFiberFromTypeAndProps (node_modules/react-dom/cjs/react-dom.development.js:23965:21)
at Object.<anonymous> (tests/components/ForecastGraph/ForecastGraph.test.jsx:27:19)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)