我想在调整图表大小时使其具有响应性。我正在使用两个图表库来处理具有响应网格布局的图表。(1)重新绘制React图表(2)react highcharts我的react recharts调整工作正常,他们是响应的,但highcharts没有响应,当我尝试调整他们的大小,他们保持不变。有人能帮助我吗?下面是代码。这是我的react网格布局代码。也看图表图像。在调整大小这个空白区域应该填充图表宽度。
import React, { useState } from 'react';
import { Responsive as ResponsiveGridLayout } from 'react-grid-layout';
import { withSize } from 'react-sizeme';
import { withSnackbar } from 'notistack';
import html2canvas from 'html2canvas';
import { jsPDF } from 'jspdf';
import TopBar from './TopBar';
import Widget from './Widget';
import OverallAttendanceChart from './AttendanceCharts/OverallAttendanceChart';
import HeadlinesChart from './AttendanceCharts/HeadlinesChart';
import LineChartView from './AttendanceCharts/LineChart';
import MonthlyChart from './AttendanceCharts/MonthlyChart';
import DateChart from './AttendanceCharts/DateChart';
import MatrixChart from './AttendanceCharts/MatrixChart';
import WardsChart from './AttendanceCharts/WardsChart';
import GroupedPieChart from './AttendanceCharts/GroupedPieChart';
import StudentsAttendance from './StudentsAttendance';
import Headlines from './Headlines';
import { Box } from '@material-ui/core';
import { CourseBasedAttendence } from '../Attendance/AttendanceCharts/CourseBasedAttendence';
import ReportsFilter from '../ReportsFilter';
const originalItems = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
];
const initialLayouts = {
lg: [
{ w: 4, h: 8, x: 0, y: 0, i: 'a', moved: false, static: false },
{ w: 12, h: 8, x: 0, y: 0, i: 'b', moved: false, static: false },
{ w: 12, h: 6, x: 6, y: 0, i: 'c', moved: false, static: false },
{ w: 6, h: 6, x: 0, y: 6, i: 'd', moved: false, static: false },
{ w: 12, h: 12, x: 0, y: 0, i: 'e', moved: false, static: false },
{ w: 12, h: 12, x: 0, y: 0, i: 'f', moved: false, static: false },
{ w: 12, h: 6, x: 6, y: 0, i: 'g', moved: false, static: false },
{ w: 6, h: 6, x: 0, y: 0, i: 'h', moved: false, static: false },
{ w: 12, h: 7, x: 6, y: 0, i: 'i', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'j', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'k', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'l', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'm', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'n', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'o', moved: false, static: false },
{ w: 4, h: 8, x: 0, y: 0, i: 'p', moved: false, static: false },
],
};
const componentList = {
a: OverallAttendanceChart,
b: GroupedPieChart,
c: LineChartView,
d: MonthlyChart,
e: HeadlinesChart,
f: DateChart,
g: MatrixChart,
h: WardsChart,
i: CourseBasedAttendence,
j: OverallAttendanceChart,
k: OverallAttendanceChart,
l: OverallAttendanceChart,
m: OverallAttendanceChart,
n: OverallAttendanceChart,
o: OverallAttendanceChart,
p: OverallAttendanceChart,
};
function Attendance({
size: { width },
enqueueSnackbar,
averageMarkLevel,
fetchCourseBasedAttendance,
courseBasedStudentList,
courseList,
reportType,
totalStudents,
coursesAttendance,
timeMonthAttendance,
}) {
const [items, setItems] = useState(originalItems);
const [layouts, setLayouts] = useState(
getFromLS('layouts') || initialLayouts,
);
const onLayoutChange = (_, allLayouts) => {
setLayouts(allLayouts);
};
const onLayoutSave = () => {
saveToLS('layouts', layouts);
};
const onRemoveItem = itemId => {
setItems(items.filter(i => i !== itemId));
};
const onAddItem = itemId => {
setItems([...items, itemId]);
};
const printDocument = () => {
enqueueSnackbar('Downloading pdf...', {
variant: 'success',
autoHideDuration: 5000,
});
const input = document.getElementById('divToPrint1');
html2canvas(input).then(canvas => {
const imgWidth = 210;
const pageHeight = 295;
const imgHeight = (canvas.height * imgWidth) / canvas.width;
let heightLeft = imgHeight;
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('portrait', 'mm', 'a4');
let position = 0;
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
pdf.save('download.pdf');
});
};
return (
<div id="divToPrint1">
<Box
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
}}
>
<ReportsFilter
fetchCourseBasedAttendance={fetchCourseBasedAttendance}
courseList={courseList}
reportType={reportType}
/>
<TopBar
onLayoutSave={onLayoutSave}
items={items}
onRemoveItem={onRemoveItem}
onAddItem={onAddItem}
originalItems={originalItems}
pdf={printDocument}
/>
</Box>
<StudentsAttendance totalStudents={totalStudents} />
<Headlines totalStudents={totalStudents} />
<ResponsiveGridLayout
className="layout"
layouts={layouts}
breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={70}
width={width}
onLayoutChange={onLayoutChange}
>
{items.map(key => (
<div
key={key}
className="widget"
data-grid={{ w: 3, h: 2, x: 0, y: Infinity }}
>
<Widget
id={key}
onRemoveItem={onRemoveItem}
component={componentList[key]}
averageMarkLevel={averageMarkLevel}
courseBasedStudentList={courseBasedStudentList}
totalStudents={totalStudents}
coursesAttendance={coursesAttendance}
timeMonthAttendance={timeMonthAttendance}
/>
</div>
))}
</ResponsiveGridLayout>
</div>
);
}
export default withSnackbar(
withSize({ refreshMode: 'debounce', refreshRate: 60 })(Attendance),
);
function getFromLS(key, reportId) {
let ls = {};
if (global.localStorage) {
try {
ls = JSON.parse(global.localStorage.getItem(`rgl-${reportId}`)) || {};
} catch (e) {}
}
return ls[key];
}
function saveToLS(key, value, reportId) {
if (global.localStorage) {
global.localStorage.setItem(
`rgl-${reportId}`,
JSON.stringify({
[key]: value,
}),
);
}
}
This is my widget.js code
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import Typography from '@material-ui/core/Typography';
const useStyles = makeStyles({
root: {
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
},
header: {
display: 'flex',
alignItems: 'center',
padding: '0.5rem',
},
spacer: {
flexGrow: 1,
},
body: {
padding: '0.5rem',
flexGrow: 1,
},
typo: {
textTransform: 'capitalize',
},
});
const widgetNames = {
a: 'Overall Attendance',
b: 'Micro-cohorts',
c: 'Attendance by Courses',
d: 'No. of attendees by Months',
e: 'Headline Chart',
f: 'Attendance over Time',
g: 'Attendance by Matrix',
h: 'Individual Wards',
i: 'Course Based Attendance',
j: 'Boys ',
k: 'Attendance for Pupil Premium (PP)',
l: 'Attendance for Non- Pupil Premium (PP)',
m: 'White British ',
n: 'Non White British ',
o: 'Attendance for English as Additional Language (EAL) ',
p: 'Attendance for Non-English as Additional Language (EAL) ',
};
export default function Widget({
id,
onRemoveItem,
component: Item,
averageMarkLevel,
courseBasedStudentList,
totalStudents,
coursesAttendance,
timeMonthAttendance,
}) {
const classes = useStyles();
return (
<Card className={classes.root}>
<div className={classes.header}>
<Typography variant="h6" gutterBottom className={classes.typo}>
{widgetNames[id]}
</Typography>
<div className={classes.spacer} />
<IconButton aria-label="delete" onClick={() => onRemoveItem(id)}>
<CloseIcon fontSize="small" />
</IconButton>
</div>
<div className={classes.body}>
<Item
averageMarkLevel={averageMarkLevel}
courseBasedStudentList={courseBasedStudentList}
totalStudents={totalStudents}
coursesAttendance={coursesAttendance}
timeMonthAttendance={timeMonthAttendance}
/>
</div>
</Card>
);
}
This is my highcharts code
import React from 'react';
import Highcharts from 'highcharts/highcharts';
import highchartsMore from 'highcharts/highcharts-more';
import solidGauge from 'highcharts/modules/solid-gauge';
import HighchartsReact from 'highcharts-react-official';
highchartsMore(Highcharts);
solidGauge(Highcharts);
const chartOptions = {
chart: {
type: 'solidgauge',
},
credits: {
enabled: false,
},
title: {
text: '',
},
pane: {
center: ['50%', '70%'],
size: '100%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc',
},
},
yAxis: {
min: 0,
max: 100,
stops: [[0, '#ff3118'], [0.5, '#ffd600'], [1, '#00bc06']],
lineWidth: 0,
tickWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70,
},
labels: {
y: 16,
},
},
exporting: {
enabled: false,
},
tooltip: {
enabled: false,
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true,
},
},
},
};
const chartOptionsLevel = {
chart: {
type: 'solidgauge',
},
credits: {
enabled: false,
},
title: {
text: 'Level',
},
pane: {
center: ['50%', '70%'],
size: '100%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc',
},
},
yAxis: {
min: 0,
max: 100,
stops: [[0, '#ff3118'], [0.5, '#ffd600'], [1, '#00bc06']],
lineWidth: 0,
tickWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70,
},
labels: {
y: 16,
},
},
exporting: {
enabled: false,
},
tooltip: {
enabled: false,
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true,
},
},
},
};
const data = 65.14666666666666;
const getChartOptions = (size, anchorEl, range, title) => {
if (size) {
chartOptions.chart.width = size.width;
chartOptions.chart.height = size.height;
}
if (typeof data === 'number') {
chartOptions.series = [
{
data: [parseFloat(data.toFixed(2))],
dataLabels: {
format:
'<div style="text-align:center">' +
'<span style="font-size:22px">{y}</span><br/>' +
'<span style="font-size:12px;opacity:0.4">%</span>' +
'</div>',
},
tooltip: {
valueSuffix: '%',
},
},
];
if (anchorEl) Highcharts.chart(anchorEl, chartOptions);
}
if (typeof range === 'number') {
chartOptions.yAxis.max = range;
}
if (title && title.length > 1) {
chartOptions.title.text = title;
}
if (title === 'Level') {
chartOptionsLevel.series = [
{
data: [parseFloat(data.toFixed(2))],
dataLabels: {
format:
'<div style="text-align:center">' +
'<span style="font-size:22px">{y}</span><br/>' +
'<span style="font-size:12px;opacity:0.4">%</span>' +
'</div>',
},
tooltip: {
valueSuffix: '%',
},
},
];
chartOptionsLevel.yAxis.max = range;
return chartOptionsLevel;
}
return JSON.parse(JSON.stringify(chartOptions));
};
function OverallAttendanceChart(props) {
const { size, anchorEl, range, title } = props;
return (
<HighchartsReact
highcharts={Highcharts}
options={getChartOptions(data, size, anchorEl, range, title)}
/>
);
}
export default OverallAttendanceChart;
1条答案
按热度按时间mrphzbgm1#