Spaces:
Sleeping
Sleeping
Guilherme Silberfarb Costa commited on
Commit ·
a14bed6
1
Parent(s): d953b73
Refine diagnostic section layout
Browse files- frontend/src/components/ElaboracaoTab.jsx +143 -156
- frontend/src/styles.css +14 -1
frontend/src/components/ElaboracaoTab.jsx
CHANGED
|
@@ -711,6 +711,9 @@ function ScatterPlotCarousel({
|
|
| 711 |
sectionFilePrefix,
|
| 712 |
onDownloadFigure,
|
| 713 |
onDownloadAll,
|
|
|
|
|
|
|
|
|
|
| 714 |
loading = false,
|
| 715 |
downloadingAssets = false,
|
| 716 |
}) {
|
|
@@ -748,7 +751,9 @@ function ScatterPlotCarousel({
|
|
| 748 |
}
|
| 749 |
|
| 750 |
function buildFileNameBase(item, itemIndex) {
|
| 751 |
-
return
|
|
|
|
|
|
|
| 752 |
}
|
| 753 |
|
| 754 |
return (
|
|
@@ -761,12 +766,12 @@ function ScatterPlotCarousel({
|
|
| 761 |
onClick={onDownloadAll}
|
| 762 |
disabled={loading || downloadingAssets || safeItems.length === 0}
|
| 763 |
>
|
| 764 |
-
|
| 765 |
</button>
|
| 766 |
</div>
|
| 767 |
) : null}
|
| 768 |
{totalPages > 1 ? (
|
| 769 |
-
<div className="scatter-carousel-pills" aria-label=
|
| 770 |
{Array.from({ length: totalPages }, (_, pageIndex) => {
|
| 771 |
const pairStart = (pageIndex * pageSize) + 1
|
| 772 |
const pairEnd = Math.min(pairStart + pageSize - 1, safeItems.length)
|
|
@@ -786,28 +791,38 @@ function ScatterPlotCarousel({
|
|
| 786 |
})}
|
| 787 |
</div>
|
| 788 |
) : null}
|
| 789 |
-
<div className=
|
| 790 |
{visibleItems.map((item, visibleIndex) => {
|
| 791 |
const itemIndex = startIndex + visibleIndex
|
| 792 |
const fileNameBase = buildFileNameBase(item, itemIndex)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 793 |
return (
|
| 794 |
<PlotFigure
|
| 795 |
-
key={`${itemKeyPrefix}-${item.id}`}
|
| 796 |
figure={item.figure}
|
| 797 |
-
indexedFigure={indexedFigureMap?.get(String(item.label || '').trim()) || null}
|
| 798 |
-
onRequestIndexedFigure={onRequestIndexedFigure}
|
| 799 |
title={item.title}
|
| 800 |
subtitle={item.subtitle}
|
| 801 |
-
showPointIndexToggle
|
| 802 |
-
forceHideLegend
|
| 803 |
-
className=
|
| 804 |
lazy
|
| 805 |
headerActions={typeof onDownloadFigure === 'function' ? (
|
| 806 |
<button
|
| 807 |
type="button"
|
| 808 |
className="btn-download-subtle plot-card-download-btn"
|
| 809 |
title={item.legenda || item.label || 'Fazer download'}
|
| 810 |
-
onClick={() => onDownloadFigure(item.figure, fileNameBase,
|
| 811 |
disabled={loading || downloadingAssets || !item.figure}
|
| 812 |
>
|
| 813 |
Fazer download
|
|
@@ -969,17 +984,25 @@ function getDispersaoYLabel(eixoYTipo, eixoYResiduo, eixoYColuna, colunaYComRotu
|
|
| 969 |
return `${colunaYComRotulo} transformado`
|
| 970 |
}
|
| 971 |
|
| 972 |
-
function DiagnosticPngCard({ title, pngPayload, alt }) {
|
| 973 |
if (!pngPayload?.image_base64) {
|
| 974 |
return (
|
| 975 |
<div className="empty-box">Grafico indisponivel.</div>
|
| 976 |
)
|
| 977 |
}
|
| 978 |
const mime = String(pngPayload.mime_type || 'image/png').trim() || 'image/png'
|
|
|
|
| 979 |
return (
|
| 980 |
-
<div className=
|
| 981 |
<div className="plot-card-head">
|
| 982 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 983 |
</div>
|
| 984 |
<img
|
| 985 |
src={`data:${mime};base64,${pngPayload.image_base64}`}
|
|
@@ -5723,9 +5746,8 @@ export default function ElaboracaoTab({ sessionId, authUser, quickLoadRequest =
|
|
| 5723 |
{[
|
| 5724 |
{ id: 'diagnosticos', label: 'Diagnósticos' },
|
| 5725 |
{ id: 'testes', label: 'Testes' },
|
| 5726 |
-
{ id: 'equacoes', label: 'Equações' },
|
| 5727 |
{ id: 'coeficientes', label: 'Coeficientes' },
|
| 5728 |
-
{ id: '
|
| 5729 |
].map((tab) => (
|
| 5730 |
<button
|
| 5731 |
key={`sec14-tab-${tab.id}`}
|
|
@@ -5769,17 +5791,6 @@ export default function ElaboracaoTab({ sessionId, authUser, quickLoadRequest =
|
|
| 5769 |
)
|
| 5770 |
) : null}
|
| 5771 |
|
| 5772 |
-
{section14Tab === 'equacoes' ? (
|
| 5773 |
-
<div className="equation-formats-section section14-equations-panel">
|
| 5774 |
-
<h4>Equações do Modelo</h4>
|
| 5775 |
-
<EquationFormatsPanel
|
| 5776 |
-
equacoes={fit.equacoes}
|
| 5777 |
-
onDownload={(mode) => void onDownloadEquacao(mode)}
|
| 5778 |
-
disabled={loading || downloadingAssets}
|
| 5779 |
-
/>
|
| 5780 |
-
</div>
|
| 5781 |
-
) : null}
|
| 5782 |
-
|
| 5783 |
{section14Tab === 'coeficientes' ? (
|
| 5784 |
<div className="section14-table-panel">
|
| 5785 |
<div className="section14-table-head">
|
|
@@ -5797,20 +5808,14 @@ export default function ElaboracaoTab({ sessionId, authUser, quickLoadRequest =
|
|
| 5797 |
</div>
|
| 5798 |
) : null}
|
| 5799 |
|
| 5800 |
-
{section14Tab === '
|
| 5801 |
-
<div className="section14-
|
| 5802 |
-
<
|
| 5803 |
-
|
| 5804 |
-
|
| 5805 |
-
|
| 5806 |
-
|
| 5807 |
-
|
| 5808 |
-
disabled={loading || downloadingAssets || !fit.tabela_obs_calc}
|
| 5809 |
-
>
|
| 5810 |
-
Fazer download
|
| 5811 |
-
</button>
|
| 5812 |
-
</div>
|
| 5813 |
-
<DataTable table={fit.tabela_obs_calc} maxHeight={460} />
|
| 5814 |
</div>
|
| 5815 |
) : null}
|
| 5816 |
</div>
|
|
@@ -5822,112 +5827,94 @@ export default function ElaboracaoTab({ sessionId, authUser, quickLoadRequest =
|
|
| 5822 |
Modo PNG automático para mais de {fit.graficos_diagnostico_limiar_png || 1500} pontos. Ao final da seção, podem ser gerados individualmente os gráficos interativos.
|
| 5823 |
</div>
|
| 5824 |
) : null}
|
| 5825 |
-
|
| 5826 |
-
<
|
| 5827 |
-
|
| 5828 |
-
|
| 5829 |
-
|
| 5830 |
-
|
| 5831 |
-
|
| 5832 |
-
|
| 5833 |
-
|
| 5834 |
-
|
| 5835 |
-
|
| 5836 |
-
|
| 5837 |
-
|
| 5838 |
-
</button>
|
| 5839 |
-
<button
|
| 5840 |
-
type="button"
|
| 5841 |
-
className="btn-download-subtle"
|
| 5842 |
-
onClick={() => (
|
| 5843 |
-
secao15DiagnosticoPng
|
| 5844 |
-
? onDownloadPngBase64(fit.grafico_residuos_png?.image_base64, fit.grafico_residuos_png?.mime_type, 'secao15_residuos')
|
| 5845 |
-
: onDownloadFigurePng(fit.grafico_residuos, 'secao15_residuos')
|
| 5846 |
-
)}
|
| 5847 |
-
disabled={loading || downloadingAssets || (secao15DiagnosticoPng ? !fit.grafico_residuos_png?.image_base64 : !fit.grafico_residuos)}
|
| 5848 |
-
>
|
| 5849 |
-
Resíduos
|
| 5850 |
-
</button>
|
| 5851 |
-
<button
|
| 5852 |
-
type="button"
|
| 5853 |
-
className="btn-download-subtle"
|
| 5854 |
-
onClick={() => (
|
| 5855 |
-
secao15DiagnosticoPng
|
| 5856 |
-
? onDownloadPngBase64(fit.grafico_histograma_png?.image_base64, fit.grafico_histograma_png?.mime_type, 'secao15_histograma')
|
| 5857 |
-
: onDownloadFigurePng(fit.grafico_histograma, 'secao15_histograma')
|
| 5858 |
-
)}
|
| 5859 |
-
disabled={loading || downloadingAssets || (secao15DiagnosticoPng ? !fit.grafico_histograma_png?.image_base64 : !fit.grafico_histograma)}
|
| 5860 |
-
>
|
| 5861 |
-
Histograma
|
| 5862 |
-
</button>
|
| 5863 |
-
<button
|
| 5864 |
-
type="button"
|
| 5865 |
-
className="btn-download-subtle"
|
| 5866 |
-
onClick={() => (
|
| 5867 |
-
secao15DiagnosticoPng
|
| 5868 |
-
? onDownloadPngBase64(fit.grafico_cook_png?.image_base64, fit.grafico_cook_png?.mime_type, 'secao15_cook')
|
| 5869 |
-
: onDownloadFigurePng(fit.grafico_cook, 'secao15_cook', { forceHideLegend: true })
|
| 5870 |
-
)}
|
| 5871 |
-
disabled={loading || downloadingAssets || (secao15DiagnosticoPng ? !fit.grafico_cook_png?.image_base64 : !fit.grafico_cook)}
|
| 5872 |
-
>
|
| 5873 |
-
Cook
|
| 5874 |
-
</button>
|
| 5875 |
-
<button
|
| 5876 |
-
type="button"
|
| 5877 |
-
className="btn-download-subtle"
|
| 5878 |
-
onClick={() => onDownloadFigurePng(fit.grafico_correlacao, 'secao15_correlacao')}
|
| 5879 |
-
disabled={loading || downloadingAssets || !fit.grafico_correlacao}
|
| 5880 |
-
>
|
| 5881 |
-
Correlação
|
| 5882 |
-
</button>
|
| 5883 |
-
<button
|
| 5884 |
-
type="button"
|
| 5885 |
-
className="btn-download-subtle"
|
| 5886 |
-
onClick={() => {
|
| 5887 |
-
if (secao15DiagnosticoPng) {
|
| 5888 |
-
void onDownloadPngBase64Batch([
|
| 5889 |
{ imageBase64: fit.grafico_obs_calc_png?.image_base64, mimeType: fit.grafico_obs_calc_png?.mime_type, fileNameBase: 'secao15_obs_calc' },
|
| 5890 |
{ imageBase64: fit.grafico_residuos_png?.image_base64, mimeType: fit.grafico_residuos_png?.mime_type, fileNameBase: 'secao15_residuos' },
|
| 5891 |
{ imageBase64: fit.grafico_histograma_png?.image_base64, mimeType: fit.grafico_histograma_png?.mime_type, fileNameBase: 'secao15_histograma' },
|
| 5892 |
{ imageBase64: fit.grafico_cook_png?.image_base64, mimeType: fit.grafico_cook_png?.mime_type, fileNameBase: 'secao15_cook' },
|
| 5893 |
-
]
|
| 5894 |
-
|
| 5895 |
-
|
| 5896 |
-
|
| 5897 |
-
|
| 5898 |
-
|
| 5899 |
-
|
| 5900 |
-
|
| 5901 |
-
{ figure: fit.grafico_correlacao, fileNameBase: 'secao15_correlacao' },
|
| 5902 |
-
])
|
| 5903 |
}}
|
| 5904 |
-
|
| 5905 |
-
|
| 5906 |
-
|
| 5907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5908 |
)}
|
| 5909 |
-
|
| 5910 |
-
|
| 5911 |
-
|
| 5912 |
-
</div>
|
| 5913 |
-
{secao15DiagnosticoPng ? (
|
| 5914 |
-
<div className="plot-grid-2-fixed">
|
| 5915 |
-
<DiagnosticPngCard title="Obs x Calc" pngPayload={fit.grafico_obs_calc_png} alt="Obs x Calc em PNG" />
|
| 5916 |
-
<DiagnosticPngCard title="Resíduos" pngPayload={fit.grafico_residuos_png} alt="Resíduos em PNG" />
|
| 5917 |
-
<DiagnosticPngCard title="Histograma" pngPayload={fit.grafico_histograma_png} alt="Histograma em PNG" />
|
| 5918 |
-
<DiagnosticPngCard title="Cook" pngPayload={fit.grafico_cook_png} alt="Cook em PNG" />
|
| 5919 |
-
</div>
|
| 5920 |
) : (
|
| 5921 |
-
<
|
| 5922 |
-
|
| 5923 |
-
|
| 5924 |
-
|
| 5925 |
-
|
| 5926 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5927 |
)}
|
| 5928 |
-
<div className="plot-full-width">
|
| 5929 |
-
<PlotFigure figure={fit.grafico_correlacao} title="Matriz de correlação" showPointIndexToggle className="plot-correlation-card" />
|
| 5930 |
-
</div>
|
| 5931 |
{secao15DiagnosticoPng ? (
|
| 5932 |
<>
|
| 5933 |
<div className="scatter-interactive-control">
|
|
@@ -5946,23 +5933,6 @@ export default function ElaboracaoTab({ sessionId, authUser, quickLoadRequest =
|
|
| 5946 |
</div>
|
| 5947 |
{secao15InterativoSelecionado !== 'none' ? (
|
| 5948 |
<>
|
| 5949 |
-
<div className="download-actions-bar">
|
| 5950 |
-
<button
|
| 5951 |
-
type="button"
|
| 5952 |
-
className="btn-download-subtle"
|
| 5953 |
-
onClick={() => {
|
| 5954 |
-
if (!secao15InterativoFigura) return
|
| 5955 |
-
void onDownloadFigurePng(
|
| 5956 |
-
secao15InterativoFigura,
|
| 5957 |
-
`secao15_${sanitizeFileName(secao15InterativoLabel, 'diagnostico_interativo')}`,
|
| 5958 |
-
{ forceHideLegend: secao15InterativoSelecionado === 'cook' },
|
| 5959 |
-
)
|
| 5960 |
-
}}
|
| 5961 |
-
disabled={loading || downloadingAssets || !secao15InterativoFigura}
|
| 5962 |
-
>
|
| 5963 |
-
Fazer download
|
| 5964 |
-
</button>
|
| 5965 |
-
</div>
|
| 5966 |
{secao15InterativoFigura ? (
|
| 5967 |
<PlotFigure
|
| 5968 |
key={`s15-interativo-${secao15InterativoSelecionado}`}
|
|
@@ -5974,6 +5944,23 @@ export default function ElaboracaoTab({ sessionId, authUser, quickLoadRequest =
|
|
| 5974 |
forceHideLegend={secao15InterativoSelecionado === 'cook'}
|
| 5975 |
className="plot-stretch"
|
| 5976 |
lazy
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5977 |
/>
|
| 5978 |
) : (
|
| 5979 |
<div className="empty-box">Grafico indisponivel.</div>
|
|
|
|
| 711 |
sectionFilePrefix,
|
| 712 |
onDownloadFigure,
|
| 713 |
onDownloadAll,
|
| 714 |
+
renderItem = null,
|
| 715 |
+
downloadAllLabel = 'Baixar todos os gráficos',
|
| 716 |
+
pillsAriaLabel = 'Escolher dupla de gráficos',
|
| 717 |
loading = false,
|
| 718 |
downloadingAssets = false,
|
| 719 |
}) {
|
|
|
|
| 751 |
}
|
| 752 |
|
| 753 |
function buildFileNameBase(item, itemIndex) {
|
| 754 |
+
if (item?.fileNameBase) return sanitizeFileName(item.fileNameBase, `grafico_${itemIndex + 1}`)
|
| 755 |
+
const prefix = sectionFilePrefix ? `${sectionFilePrefix}_` : ''
|
| 756 |
+
return `${prefix}${sanitizeFileName(item?.label, `dispersao_${itemIndex + 1}`)}`
|
| 757 |
}
|
| 758 |
|
| 759 |
return (
|
|
|
|
| 766 |
onClick={onDownloadAll}
|
| 767 |
disabled={loading || downloadingAssets || safeItems.length === 0}
|
| 768 |
>
|
| 769 |
+
{downloadAllLabel}
|
| 770 |
</button>
|
| 771 |
</div>
|
| 772 |
) : null}
|
| 773 |
{totalPages > 1 ? (
|
| 774 |
+
<div className="scatter-carousel-pills" aria-label={pillsAriaLabel}>
|
| 775 |
{Array.from({ length: totalPages }, (_, pageIndex) => {
|
| 776 |
const pairStart = (pageIndex * pageSize) + 1
|
| 777 |
const pairEnd = Math.min(pairStart + pageSize - 1, safeItems.length)
|
|
|
|
| 791 |
})}
|
| 792 |
</div>
|
| 793 |
) : null}
|
| 794 |
+
<div className={`scatter-carousel-track${visibleItems.length === 1 ? ' is-single' : ''}`}>
|
| 795 |
{visibleItems.map((item, visibleIndex) => {
|
| 796 |
const itemIndex = startIndex + visibleIndex
|
| 797 |
const fileNameBase = buildFileNameBase(item, itemIndex)
|
| 798 |
+
if (typeof renderItem === 'function') {
|
| 799 |
+
return (
|
| 800 |
+
<React.Fragment key={`${itemKeyPrefix}-${item.id || itemIndex}`}>
|
| 801 |
+
{renderItem({ item, itemIndex, fileNameBase })}
|
| 802 |
+
</React.Fragment>
|
| 803 |
+
)
|
| 804 |
+
}
|
| 805 |
+
const forceHideLegend = item.forceHideLegend ?? true
|
| 806 |
+
const showPointIndexToggle = item.showPointIndexToggle ?? true
|
| 807 |
+
const downloadOptions = item.downloadOptions || { forceHideLegend }
|
| 808 |
return (
|
| 809 |
<PlotFigure
|
| 810 |
+
key={`${itemKeyPrefix}-${item.id || itemIndex}`}
|
| 811 |
figure={item.figure}
|
| 812 |
+
indexedFigure={item.indexedFigure || indexedFigureMap?.get(String(item.label || '').trim()) || null}
|
| 813 |
+
onRequestIndexedFigure={item.onRequestIndexedFigure || onRequestIndexedFigure}
|
| 814 |
title={item.title}
|
| 815 |
subtitle={item.subtitle}
|
| 816 |
+
showPointIndexToggle={showPointIndexToggle}
|
| 817 |
+
forceHideLegend={forceHideLegend}
|
| 818 |
+
className={item.className || 'plot-stretch'}
|
| 819 |
lazy
|
| 820 |
headerActions={typeof onDownloadFigure === 'function' ? (
|
| 821 |
<button
|
| 822 |
type="button"
|
| 823 |
className="btn-download-subtle plot-card-download-btn"
|
| 824 |
title={item.legenda || item.label || 'Fazer download'}
|
| 825 |
+
onClick={() => onDownloadFigure(item.figure, fileNameBase, downloadOptions)}
|
| 826 |
disabled={loading || downloadingAssets || !item.figure}
|
| 827 |
>
|
| 828 |
Fazer download
|
|
|
|
| 984 |
return `${colunaYComRotulo} transformado`
|
| 985 |
}
|
| 986 |
|
| 987 |
+
function DiagnosticPngCard({ title, pngPayload, alt, headerActions = null, className = '' }) {
|
| 988 |
if (!pngPayload?.image_base64) {
|
| 989 |
return (
|
| 990 |
<div className="empty-box">Grafico indisponivel.</div>
|
| 991 |
)
|
| 992 |
}
|
| 993 |
const mime = String(pngPayload.mime_type || 'image/png').trim() || 'image/png'
|
| 994 |
+
const cardClassName = `plot-card plot-png-card ${className}`.trim()
|
| 995 |
return (
|
| 996 |
+
<div className={cardClassName}>
|
| 997 |
<div className="plot-card-head">
|
| 998 |
+
<div className="plot-card-head-main">
|
| 999 |
+
<h4 className="plot-card-title">{title}</h4>
|
| 1000 |
+
</div>
|
| 1001 |
+
{headerActions ? (
|
| 1002 |
+
<div className="plot-card-head-actions">
|
| 1003 |
+
{headerActions}
|
| 1004 |
+
</div>
|
| 1005 |
+
) : null}
|
| 1006 |
</div>
|
| 1007 |
<img
|
| 1008 |
src={`data:${mime};base64,${pngPayload.image_base64}`}
|
|
|
|
| 5746 |
{[
|
| 5747 |
{ id: 'diagnosticos', label: 'Diagnósticos' },
|
| 5748 |
{ id: 'testes', label: 'Testes' },
|
|
|
|
| 5749 |
{ id: 'coeficientes', label: 'Coeficientes' },
|
| 5750 |
+
{ id: 'equacoes', label: 'Equações' },
|
| 5751 |
].map((tab) => (
|
| 5752 |
<button
|
| 5753 |
key={`sec14-tab-${tab.id}`}
|
|
|
|
| 5791 |
)
|
| 5792 |
) : null}
|
| 5793 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5794 |
{section14Tab === 'coeficientes' ? (
|
| 5795 |
<div className="section14-table-panel">
|
| 5796 |
<div className="section14-table-head">
|
|
|
|
| 5808 |
</div>
|
| 5809 |
) : null}
|
| 5810 |
|
| 5811 |
+
{section14Tab === 'equacoes' ? (
|
| 5812 |
+
<div className="equation-formats-section section14-equations-panel">
|
| 5813 |
+
<h4>Equações do Modelo</h4>
|
| 5814 |
+
<EquationFormatsPanel
|
| 5815 |
+
equacoes={fit.equacoes}
|
| 5816 |
+
onDownload={(mode) => void onDownloadEquacao(mode)}
|
| 5817 |
+
disabled={loading || downloadingAssets}
|
| 5818 |
+
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5819 |
</div>
|
| 5820 |
) : null}
|
| 5821 |
</div>
|
|
|
|
| 5827 |
Modo PNG automático para mais de {fit.graficos_diagnostico_limiar_png || 1500} pontos. Ao final da seção, podem ser gerados individualmente os gráficos interativos.
|
| 5828 |
</div>
|
| 5829 |
) : null}
|
| 5830 |
+
{secao15DiagnosticoPng ? (
|
| 5831 |
+
<ScatterPlotCarousel
|
| 5832 |
+
items={[
|
| 5833 |
+
{ id: 'obs_calc_png', type: 'png', label: 'Obs x Calc', title: 'Obs x Calc', pngPayload: fit.grafico_obs_calc_png, fileNameBase: 'secao15_obs_calc' },
|
| 5834 |
+
{ id: 'residuos_png', type: 'png', label: 'Resíduos', title: 'Resíduos', pngPayload: fit.grafico_residuos_png, fileNameBase: 'secao15_residuos' },
|
| 5835 |
+
{ id: 'histograma_png', type: 'png', label: 'Histograma', title: 'Histograma', pngPayload: fit.grafico_histograma_png, fileNameBase: 'secao15_histograma' },
|
| 5836 |
+
{ id: 'cook_png', type: 'png', label: 'Cook', title: 'Cook', pngPayload: fit.grafico_cook_png, fileNameBase: 'secao15_cook' },
|
| 5837 |
+
{ id: 'correlacao', type: 'figure', label: 'Correlação', title: 'Matriz de correlação', figure: fit.grafico_correlacao, fileNameBase: 'secao15_correlacao', className: 'plot-stretch plot-correlation-card' },
|
| 5838 |
+
]}
|
| 5839 |
+
itemKeyPrefix="s15-png"
|
| 5840 |
+
onDownloadAll={() => {
|
| 5841 |
+
void (async () => {
|
| 5842 |
+
const pngDownloads = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5843 |
{ imageBase64: fit.grafico_obs_calc_png?.image_base64, mimeType: fit.grafico_obs_calc_png?.mime_type, fileNameBase: 'secao15_obs_calc' },
|
| 5844 |
{ imageBase64: fit.grafico_residuos_png?.image_base64, mimeType: fit.grafico_residuos_png?.mime_type, fileNameBase: 'secao15_residuos' },
|
| 5845 |
{ imageBase64: fit.grafico_histograma_png?.image_base64, mimeType: fit.grafico_histograma_png?.mime_type, fileNameBase: 'secao15_histograma' },
|
| 5846 |
{ imageBase64: fit.grafico_cook_png?.image_base64, mimeType: fit.grafico_cook_png?.mime_type, fileNameBase: 'secao15_cook' },
|
| 5847 |
+
]
|
| 5848 |
+
if (pngDownloads.some((item) => String(item.imageBase64 || '').trim())) {
|
| 5849 |
+
await onDownloadPngBase64Batch(pngDownloads)
|
| 5850 |
+
}
|
| 5851 |
+
if (fit.grafico_correlacao) {
|
| 5852 |
+
await onDownloadFigurePng(fit.grafico_correlacao, 'secao15_correlacao')
|
| 5853 |
+
}
|
| 5854 |
+
})()
|
|
|
|
|
|
|
| 5855 |
}}
|
| 5856 |
+
renderItem={({ item, fileNameBase }) => (
|
| 5857 |
+
item.type === 'png' ? (
|
| 5858 |
+
<DiagnosticPngCard
|
| 5859 |
+
title={item.title}
|
| 5860 |
+
pngPayload={item.pngPayload}
|
| 5861 |
+
alt={`${item.title} em PNG`}
|
| 5862 |
+
className="plot-stretch"
|
| 5863 |
+
headerActions={(
|
| 5864 |
+
<button
|
| 5865 |
+
type="button"
|
| 5866 |
+
className="btn-download-subtle plot-card-download-btn"
|
| 5867 |
+
onClick={() => onDownloadPngBase64(item.pngPayload?.image_base64, item.pngPayload?.mime_type, fileNameBase)}
|
| 5868 |
+
disabled={loading || downloadingAssets || !item.pngPayload?.image_base64}
|
| 5869 |
+
>
|
| 5870 |
+
Fazer download
|
| 5871 |
+
</button>
|
| 5872 |
+
)}
|
| 5873 |
+
/>
|
| 5874 |
+
) : (
|
| 5875 |
+
<PlotFigure
|
| 5876 |
+
figure={item.figure}
|
| 5877 |
+
title={item.title}
|
| 5878 |
+
className={item.className}
|
| 5879 |
+
lazy
|
| 5880 |
+
headerActions={(
|
| 5881 |
+
<button
|
| 5882 |
+
type="button"
|
| 5883 |
+
className="btn-download-subtle plot-card-download-btn"
|
| 5884 |
+
onClick={() => onDownloadFigurePng(item.figure, fileNameBase)}
|
| 5885 |
+
disabled={loading || downloadingAssets || !item.figure}
|
| 5886 |
+
>
|
| 5887 |
+
Fazer download
|
| 5888 |
+
</button>
|
| 5889 |
+
)}
|
| 5890 |
+
/>
|
| 5891 |
+
)
|
| 5892 |
)}
|
| 5893 |
+
loading={loading}
|
| 5894 |
+
downloadingAssets={downloadingAssets}
|
| 5895 |
+
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5896 |
) : (
|
| 5897 |
+
<ScatterPlotCarousel
|
| 5898 |
+
items={[
|
| 5899 |
+
{ id: 'obs_calc', label: 'Obs x Calc', title: 'Obs x Calc', figure: fit.grafico_obs_calc, indexedFigure: fit.grafico_obs_calc_com_indices || null, onRequestIndexedFigure: () => ensureSecao15GraficoComIndices('obs_calc'), fileNameBase: 'secao15_obs_calc', forceHideLegend: false, downloadOptions: { forceHideLegend: false } },
|
| 5900 |
+
{ id: 'residuos', label: 'Resíduos', title: 'Resíduos', figure: fit.grafico_residuos, indexedFigure: fit.grafico_residuos_com_indices || null, onRequestIndexedFigure: () => ensureSecao15GraficoComIndices('residuos'), fileNameBase: 'secao15_residuos', forceHideLegend: false, downloadOptions: { forceHideLegend: false } },
|
| 5901 |
+
{ id: 'histograma', label: 'Histograma', title: 'Histograma', figure: fit.grafico_histograma, indexedFigure: fit.grafico_histograma_com_indices || null, onRequestIndexedFigure: () => ensureSecao15GraficoComIndices('histograma'), fileNameBase: 'secao15_histograma', forceHideLegend: false, downloadOptions: { forceHideLegend: false } },
|
| 5902 |
+
{ id: 'cook', label: 'Cook', title: 'Cook', figure: fit.grafico_cook, indexedFigure: fit.grafico_cook_com_indices || null, onRequestIndexedFigure: () => ensureSecao15GraficoComIndices('cook'), fileNameBase: 'secao15_cook', forceHideLegend: true, downloadOptions: { forceHideLegend: true } },
|
| 5903 |
+
{ id: 'correlacao', label: 'Correlação', title: 'Matriz de correlação', figure: fit.grafico_correlacao, fileNameBase: 'secao15_correlacao', forceHideLegend: false, showPointIndexToggle: false, className: 'plot-stretch plot-correlation-card', downloadOptions: { forceHideLegend: false } },
|
| 5904 |
+
]}
|
| 5905 |
+
itemKeyPrefix="s15-plot"
|
| 5906 |
+
onDownloadFigure={onDownloadFigurePng}
|
| 5907 |
+
onDownloadAll={() => onDownloadFiguresPngBatch([
|
| 5908 |
+
{ figure: fit.grafico_obs_calc, fileNameBase: 'secao15_obs_calc', forceHideLegend: false },
|
| 5909 |
+
{ figure: fit.grafico_residuos, fileNameBase: 'secao15_residuos', forceHideLegend: false },
|
| 5910 |
+
{ figure: fit.grafico_histograma, fileNameBase: 'secao15_histograma', forceHideLegend: false },
|
| 5911 |
+
{ figure: fit.grafico_cook, fileNameBase: 'secao15_cook', forceHideLegend: true },
|
| 5912 |
+
{ figure: fit.grafico_correlacao, fileNameBase: 'secao15_correlacao', forceHideLegend: false },
|
| 5913 |
+
])}
|
| 5914 |
+
loading={loading}
|
| 5915 |
+
downloadingAssets={downloadingAssets}
|
| 5916 |
+
/>
|
| 5917 |
)}
|
|
|
|
|
|
|
|
|
|
| 5918 |
{secao15DiagnosticoPng ? (
|
| 5919 |
<>
|
| 5920 |
<div className="scatter-interactive-control">
|
|
|
|
| 5933 |
</div>
|
| 5934 |
{secao15InterativoSelecionado !== 'none' ? (
|
| 5935 |
<>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5936 |
{secao15InterativoFigura ? (
|
| 5937 |
<PlotFigure
|
| 5938 |
key={`s15-interativo-${secao15InterativoSelecionado}`}
|
|
|
|
| 5944 |
forceHideLegend={secao15InterativoSelecionado === 'cook'}
|
| 5945 |
className="plot-stretch"
|
| 5946 |
lazy
|
| 5947 |
+
headerActions={(
|
| 5948 |
+
<button
|
| 5949 |
+
type="button"
|
| 5950 |
+
className="btn-download-subtle plot-card-download-btn"
|
| 5951 |
+
onClick={() => {
|
| 5952 |
+
if (!secao15InterativoFigura) return
|
| 5953 |
+
void onDownloadFigurePng(
|
| 5954 |
+
secao15InterativoFigura,
|
| 5955 |
+
`secao15_${sanitizeFileName(secao15InterativoLabel, 'diagnostico_interativo')}`,
|
| 5956 |
+
{ forceHideLegend: secao15InterativoSelecionado === 'cook' },
|
| 5957 |
+
)
|
| 5958 |
+
}}
|
| 5959 |
+
disabled={loading || downloadingAssets || !secao15InterativoFigura}
|
| 5960 |
+
>
|
| 5961 |
+
Fazer download
|
| 5962 |
+
</button>
|
| 5963 |
+
)}
|
| 5964 |
/>
|
| 5965 |
) : (
|
| 5966 |
<div className="empty-box">Grafico indisponivel.</div>
|
frontend/src/styles.css
CHANGED
|
@@ -5156,7 +5156,9 @@ button.btn-upload-select {
|
|
| 5156 |
}
|
| 5157 |
|
| 5158 |
.section14-test-card .section14-field-row {
|
| 5159 |
-
padding:
|
|
|
|
|
|
|
| 5160 |
}
|
| 5161 |
|
| 5162 |
.section14-test-card .section14-field-label {
|
|
@@ -5168,6 +5170,13 @@ button.btn-upload-select {
|
|
| 5168 |
line-height: 1.25;
|
| 5169 |
}
|
| 5170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5171 |
.section14-field-row {
|
| 5172 |
display: flex;
|
| 5173 |
justify-content: space-between;
|
|
@@ -6324,6 +6333,10 @@ button.btn-upload-select {
|
|
| 6324 |
gap: 12px;
|
| 6325 |
}
|
| 6326 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6327 |
.section-disclaimer-warning {
|
| 6328 |
margin: 0 0 10px;
|
| 6329 |
padding: 9px 12px;
|
|
|
|
| 5156 |
}
|
| 5157 |
|
| 5158 |
.section14-test-card .section14-field-row {
|
| 5159 |
+
padding: 4px 0;
|
| 5160 |
+
border-bottom: none;
|
| 5161 |
+
background: transparent;
|
| 5162 |
}
|
| 5163 |
|
| 5164 |
.section14-test-card .section14-field-label {
|
|
|
|
| 5170 |
line-height: 1.25;
|
| 5171 |
}
|
| 5172 |
|
| 5173 |
+
.section14-test-card .section14-field-grid {
|
| 5174 |
+
gap: 4px;
|
| 5175 |
+
border: none;
|
| 5176 |
+
border-radius: 0;
|
| 5177 |
+
overflow: visible;
|
| 5178 |
+
}
|
| 5179 |
+
|
| 5180 |
.section14-field-row {
|
| 5181 |
display: flex;
|
| 5182 |
justify-content: space-between;
|
|
|
|
| 6333 |
gap: 12px;
|
| 6334 |
}
|
| 6335 |
|
| 6336 |
+
.scatter-carousel-track.is-single > * {
|
| 6337 |
+
grid-column: 1 / -1;
|
| 6338 |
+
}
|
| 6339 |
+
|
| 6340 |
.section-disclaimer-warning {
|
| 6341 |
margin: 0 0 10px;
|
| 6342 |
padding: 9px 12px;
|