环保评级-报告edit icon

作者:
Fadinghaze
Fork(复制)
下载
嵌入
BUG反馈
index.html
现在支持上传本地图片了!
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分析报告 v2.1 - 二号文任务盘点-2025年第一季度</title>
    <!-- Using Chart.js for professional data visualization -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0"></script>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap');

        /* --- Global Setup --- */
        body {
            font-family: 'Noto Sans SC', sans-serif;
            background-color: #f0f2f5; /* Lighter background for a more "Excel" feel */
            display: flex;
            justify-content: center;
            align-items: flex-start;
            padding: 40px 20px;
            color: #333;
        }

        /* --- Report Container (Simulates a PDF page) --- */
        .report-container {
            background-color: #ffffff;
            width: 100%;
            max-width: 900px; /* Wider to accommodate vertical charts */
            padding: 40px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            border-radius: 4px;
            border-top: 5px solid #00bcd4;
        }

        /* --- Report Header --- */
        .report-header {
            text-align: center;
            border-bottom: 1px solid #e0e0e0;
            padding-bottom: 15px;
            margin-bottom: 30px;
        }
        .report-header h1 {
            font-size: 24px;
            font-weight: 700;
            margin: 0 0 5px 0;
            color: #112240;
        }
        .report-header p {
            font-size: 14px;
            color: #8892b0;
            margin: 0;
        }

        /* --- Section Styling --- */
        .report-section {
            margin-bottom: 45px;
        }
        .report-section h2 {
            font-size: 20px;
            font-weight: 500;
            color: #112240;
            border-bottom: 2px solid #00bcd4;
            padding-bottom: 8px;
            margin-bottom: 15px;
        }
        .analysis-summary {
            font-size: 15px;
            line-height: 1.7;
            background-color: #f8f9fa;
            padding: 15px;
            border-radius: 4px;
            border-left: 4px solid #00bcd4;
            margin-bottom: 25px;
        }
        .analysis-summary strong {
            color: #0d1b2a;
            font-weight: 500;
        }
        .chart-container {
            width: 100%;
            margin-top: 20px;
            height: 350px; /* Set a fixed height for consistency */
        }

        /* --- Summary Section Specifics --- */
        .summary-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; }
        .summary-box { padding: 20px; border-radius: 5px; }
        .summary-box h3 { margin-top: 0; font-size: 16px; font-weight: 500; margin-bottom: 15px; display: flex; align-items: center; }
        .summary-box.outstanding { background-color: #e8f5e9; border: 1px solid #a5d6a7; }
        .summary-box.improvement { background-color: #fff3e0; border: 1px solid #ffcc80; }
        .summary-list { list-style-type: none; padding-left: 0; margin: 0; }
        .summary-list li { display: flex; justify-content: space-between; padding: 8px 0; font-size: 14px; border-bottom: 1px dashed #ccc; }
        .summary-list li:last-child { border-bottom: none; }
        .summary-list .company-name {
            font-weight: 500;
            color: #333;
            /* Allow long names to wrap if needed */
            flex-basis: 70%;
            padding-right: 10px;
        }
        .summary-list .score { font-weight: bold; color: #555; white-space: nowrap; }
        .summary-box h3 .icon { margin-right: 8px; font-size: 20px; }
        .outstanding h3 .icon { color: #4caf50; }
        .improvement h3 .icon { color: #ff9800; }
    </style>
</head>
<body>

    <div class="report-container">
        <header class="report-header">
            <h1>二号文任务盘点 - 2025年第一季度分析报告</h1>
            <p>生成时间: 2025-04-05 09:18:45</p>
        </header>

        <main>
            <!-- Section 1: Task Completion -->
            <section class="report-section">
                <h2>1. 任务完成情况分析</h2>
                <p class="analysis-summary">
                    在本报告期(2025年第一季度)内,针对“二号文任务盘点”工作,共有 <strong>9</strong> 家单位参与。任务整体完成率为 <strong>98.7%</strong> (已完成 <strong>152</strong> 项 / 总计 <strong>154</strong> 项)。其中 <strong>7</strong> 家单位完成了全部指派任务,整体执行情况良好。
                </p>
                <div class="chart-container">
                    <canvas id="completionChart"></canvas>
                </div>
            </section>

            <!-- Section 2: Task Scoring -->
            <section class="report-section">
                <h2>2. 任务得分情况分析</h2>
                <p class="analysis-summary">
                    报告期内,各单位的综合得分表现优异,所有单位的平均得分为 <strong>43.1</strong> 分 (满分50分),平均得分率为 <strong>86.2%</strong>。得分率分布较为集中,最高分与最低分差距在 <strong>12%</strong> 以内,说明各单位对任务标准的理解和执行普遍到位。
                </p>
                <div class="chart-container">
                    <canvas id="scoreChart"></canvas>
                </div>
            </section>

            <!-- Section 3: Indicator Scoring -->
            <section class="report-section">
                <h2>3. 指标得分情况分析</h2>
                <p class="analysis-summary">
                    本次评价包含 <strong>3</strong> 个主要一级指标。整体来看,“<strong>(一) 切实提高政治站位</strong>” 平均得分率最高,达到 <strong>95%</strong>;而“<strong>(三) 大力弘扬生态文化</strong>” 平均得分率相对较低,为 <strong>78%</strong>,是本次评价的主要改进方向。
                </p>
                <div id="indicatorChartsContainer">
                    <!-- Charts will be generated here by JavaScript -->
                </div>
            </section>
            
            <!-- Section 4: Summary -->
            <section class="report-section">
                <h2>4. 任务总结</h2>
                <div class="summary-grid">
                    <div class="summary-box outstanding">
                        <h3><span class="icon">🏆</span>优秀单位 (综合排名前三)</h3>
                        <ul class="summary-list" id="outstanding-list">
                            <!-- Populated by JS -->
                        </ul>
                    </div>
                    <div class="summary-box improvement">
                        <h3><span class="icon">🚩</span>待改进单位 (综合排名后三)</h3>
                        <ul class="summary-list" id="improvement-list">
                           <!-- Populated by JS -->
                        </ul>
                    </div>
                </div>
            </section>

        </main>
    </div>

    <script>
    // --- Chart.js Global Configuration ---
    Chart.register(ChartDataLabels);
    Chart.defaults.font.family = "'Noto Sans SC', sans-serif";
    Chart.defaults.plugins.legend.display = false;
    Chart.defaults.plugins.datalabels.anchor = 'end';
    Chart.defaults.plugins.datalabels.align = 'end';
    Chart.defaults.plugins.datalabels.color = '#555';
    Chart.defaults.plugins.datalabels.font = { weight: 'normal', size: 11 };
    Chart.defaults.scale.grid.color = '#e0e0e0';

    // --- Data Setup ---
    const companyShortNames = new Map([
        ["国能陈家港发电有限公司", "陈家港"],
        ["国能常州发电有限公司", "常州"],
        ["国家能源集团泰州发电有限公司", "泰州"],
        ["国能太仓发电有限公司", "太仓"],
        ["江苏电力工程技术有限公司", "工程"],
        ["国能谏壁发电有限公司", "谏壁"],
        ["国能宿迁热电有限公司", "宿迁"],
        ["国能徐州发电有限公司", "徐州"],
        ["江苏新能源科技开发有限公司", "新能源"] // MODIFICATION 1: Corrected name
    ]);
    
    const fullReportData = [
        { name: "国能谏壁发电有限公司", completion: { done: 13, total: 13 }, score: { value: 62.2, max: 66 } },
        { name: "国家能源集团泰州发电有限公司", completion: { done: 15, total: 15 }, score: { value: 51.4, max: 54 } },
        { name: "国能陈家港发电有限公司", completion: { done: 22, total: 22 }, score: { value: 48.6, max: 50 } },
        { name: "国能太仓发电有限公司", completion: { done: 21, total: 21 }, score: { value: 43.1, max: 45.5 } },
        { name: "国能常州发电有限公司", completion: { done: 13, total: 13 }, score: { value: 43.2, max: 50 } },
        { name: "江苏电力工程技术有限公司", completion: { done: 5, total: 5 }, score: { value: 43.2, max: 50 } },
        { name: "国能宿迁热电有限公司", completion: { done: 17, total: 17 }, score: { value: 43.1, max: 49 } },
        { name: "国能徐州发电有限公司", completion: { done: 14, total: 16 }, score: { value: 38.9, max: 46 } },
        { name: "江苏新能源科技开发有限公司", completion: { done: 6, total: 8 }, score: { value: 12.0, max: 12 } },
    ].map(d => ({
        ...d,
        shortName: companyShortNames.get(d.name) || d.name,
        completionRate: (d.completion.done / d.completion.total) * 100,
        scoreRate: (d.score.value / d.score.max) * 100
    }));

    const sortedByCompletion = [...fullReportData].sort((a, b) => b.completionRate - a.completionRate);
    const sortedByScore = [...fullReportData].sort((a, b) => b.scoreRate - a.scoreRate);
    
    const indicatorData = [
        { 
            name: "(一) 切实提高政治站位",
            scores: [
                { name: "国能谏壁发电有限公司", score: 10, max: 10 }, { name: "国家能源集团泰州发电有限公司", score: 9.8, max: 10 }, { name: "国能陈家港发电有限公司", score: 9.8, max: 10 }, { name: "国能太仓发电有限公司", score: 9.5, max: 10 }, { name: "国能常州发电有限公司", score: 9.2, max: 10 }, { name: "江苏电力工程技术有限公司", score: 9.1, max: 10 }, { name: "国能宿迁热电有限公司", score: 9.0, max: 10 }, { name: "国能徐州发电有限公司", score: 8.5, max: 10 }, { name: "江苏新能源科技开发有限公司", score: 10, max: 10 },
            ]
        },
        { 
            name: "(二) 落实环保主体责任",
            scores: [
                { name: "国能谏壁发电有限公司", score: 19.5, max: 20 }, { name: "国家能源集团泰州发电有限公司", score: 19.0, max: 20 }, { name: "国能陈家港发电有限公司", score: 18.8, max: 20 }, { name: "国能太仓发电有限公司", score: 18.2, max: 20 }, { name: "国能宿迁热电有限公司", score: 18.0, max: 20 }, { name: "国能常州发电有限公司", score: 17.5, max: 20 }, { name: "江苏电力工程技术有限公司", score: 17.2, max: 20 }, { name: "国能徐州发电有限公司", score: 16.5, max: 20 }, { name: "江苏新能源科技开发有限公司", score: 1.0, max: 1 },
            ]
        },
        { 
            name: "(三) 大力弘扬生态文化",
            scores: [
                { name: "国能常州发电有限公司", score: 8.5, max: 10 }, { name: "国能陈家港发电有限公司", score: 8.0, max: 10 }, { name: "国能谏壁发电有限公司", score: 7.5, max: 10 }, { name: "国家能源集团泰州发电有限公司", score: 7.5, max: 10 }, { name: "国能太仓发电有限公司", score: 7.2, max: 10 }, { name: "国能宿迁热电有限公司", score: 7.0, max: 10 }, { name: "江苏电力工程技术有限公司", score: 6.8, max: 10 }, { name: "国能徐州发电有限公司", score: 6.5, max: 10 }, { name: "江苏新能源科技开发有限公司", score: 1.0, max: 1 },
            ]
        }
    ];

    // --- Chart Rendering Function ---
    function createVerticalBarChart(canvasId, chartData, valueKey, labelKey, yAxisTitle, color, dataLabelFormatter) {
        new Chart(document.getElementById(canvasId), {
            type: 'bar',
            data: {
                labels: chartData.map(d => d[labelKey]),
                datasets: [{
                    data: chartData.map(d => d[valueKey].toFixed(1)),
                    backgroundColor: color,
                    borderColor: color,
                    // MODIFICATION 3: Bar styling
                    barPercentage: 0.6,
                    maxBarThickness: 50,
                    borderRadius: 4
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: { 
                    y: { 
                        beginAtZero: true,
                        max: 110, // MODIFICATION 4: Add headroom for labels
                        title: { display: true, text: yAxisTitle, font: { size: 14 } },
                        ticks: { callback: value => value + "%" } 
                    },
                    x: {
                        // MODIFICATION 2: Remove X-axis title
                        title: { display: false }
                    }
                },
                plugins: {
                    tooltip: { enabled: false },
                    datalabels: {
                        formatter: dataLabelFormatter
                    }
                }
            }
        });
    }
    
    // 1. Completion Chart
    createVerticalBarChart('completionChart', sortedByCompletion, 'completionRate', 'shortName', '完成率 (%)', '#a5d6a7', 
        (value, context) => {
            const data = sortedByCompletion[context.dataIndex].completion;
            return `${data.done}/${data.total}`;
        }
    );

    // 2. Score Chart
    createVerticalBarChart('scoreChart', sortedByScore, 'scoreRate', 'shortName', '得分率 (%)', '#81d4fa',
        (value, context) => {
            const data = sortedByScore[context.dataIndex].score;
            return `${data.value}/${data.max}`;
        }
    );

    // 3. Indicator Charts (Dynamically Created)
    const indicatorContainer = document.getElementById('indicatorChartsContainer');
    indicatorData.forEach((indicator, index) => {
        const sectionDiv = document.createElement('div');
        sectionDiv.style.marginBottom = '40px';
        const title = document.createElement('h3');
        title.textContent = `3.${index + 1} 指标:${indicator.name}`;
        title.style.cssText = "font-size: 16px; font-weight: 500; color: #333;";
        const chartContainer = document.createElement('div');
        chartContainer.className = 'chart-container';
        const chartCanvas = document.createElement('canvas');
        chartContainer.appendChild(chartCanvas);
        sectionDiv.appendChild(title);
        sectionDiv.appendChild(chartContainer);
        indicatorContainer.appendChild(sectionDiv);
        
        const sortedIndicatorScores = indicator.scores.map(s => ({
            ...s,
            shortName: companyShortNames.get(s.name) || s.name,
            scoreRate: (s.score / s.max) * 100
        })).sort((a, b) => b.scoreRate - a.scoreRate);
        
        new Chart(chartCanvas, {
            type: 'bar',
            data: {
                labels: sortedIndicatorScores.map(d => d.shortName),
                datasets: [{
                    data: sortedIndicatorScores.map(d => d.scoreRate.toFixed(1)),
                    backgroundColor: '#d1c4e9',
                    // MODIFICATION 3: Bar styling
                    barPercentage: 0.6,
                    maxBarThickness: 50,
                    borderRadius: 4
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: { 
                    y: { 
                        beginAtZero: true, 
                        max: 110, // MODIFICATION 4: Add headroom for labels
                        title: { display: true, text: '得分率 (%)' }, 
                        ticks: { callback: v => v + '%' } 
                    },
                    x: { 
                        // MODIFICATION 2: Remove X-axis title
                        title: { display: false }
                    }
                },
                 plugins: {
                    tooltip: { enabled: false },
                    datalabels: {
                        formatter: (value, context) => {
                            const data = sortedIndicatorScores[context.dataIndex];
                            return `${data.score}/${data.max}`;
                        }
                    }
                }
            }
        });
    });

    // 4. Populate Summary Lists
    const outstandingList = document.getElementById('outstanding-list');
    const improvementList = document.getElementById('improvement-list');
    const totalUnits = sortedByScore.length;

    sortedByScore.slice(0, 3).forEach(d => {
        // MODIFICATION 5: Use full name
        outstandingList.innerHTML += `<li><span class="company-name">${d.name}</span> <span class="score">${d.scoreRate.toFixed(1)}%</span></li>`;
    });
    
    sortedByScore.slice(Math.max(totalUnits - 3, 0)).reverse().forEach(d => {
        // MODIFICATION 5: Use full name
        improvementList.innerHTML += `<li><span class="company-name">${d.name}</span> <span class="score">${d.scoreRate.toFixed(1)}%</span></li>`;
    });

    </script>
</body>
</html>
        
编辑器加载中
预览
控制台