Skip to content

八维 #2425

@qqq9996shen

Description

@qqq9996shen

Error code

ERRW:SS1.0

Were you logged in?

Yes

Your username (if logged in)

No response

Your HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>八维能力雷达图生成器 | 自定义维度</title>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
  <script src="https://cdn.tailwindcss.com"></script>
  <style>
    * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
    body { background-color: #f7f9fc; font-family: system-ui, -apple-system, "Microsoft YaHei", sans-serif; }
    .card-shadow { box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
    .level-input { width: 85px; text-align: center; }
    #radarBox { min-height: 400px; height: 62vh; }
    .dim-name, .dim-level { min-height: 38px; }
    button { min-height: 42px; }
  </style>
</head>
<body class="p-3 md:p-6">
<div class="max-w-7xl mx-auto">
  <h1 class="text-[clamp(1.3rem,5vw,2.2rem)] font-bold text-gray-800 mb-5 text-center leading-tight">八维能力雷达图生成器(自定义维度)</h1>

  <div class="flex flex-col lg:flex-row gap-5 md:gap-6">
    <div class="lg:w-[420px] w-full bg-white rounded-xl p-4 md:p-5 card-shadow">
      <div class="flex flex-wrap gap-2.5 mb-5">
        <button id="fillDefault" class="flex-1 min-w-[140px] px-3 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 active:bg-blue-800 transition">一键导入默认八维</button>
        <button id="resetAll" class="flex-1 min-w-[140px] px-3 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 active:bg-red-700 transition">重置全部数据</button>
      </div>

      <div class="mb-5 border-b pb-4">
        <h3 class="font-semibold text-gray-700 mb-3">图表基础设置</h3>
        <div class="flex flex-col gap-3">
          <div class="flex items-center gap-2 flex-wrap">
            <label class="w-[76px] shrink-0 text-sm text-gray-600">图表标题:</label>
            <input type="text" id="chartTitle" value="个人综合能力八维雷达图" class="flex-1 min-w-[160px] border rounded px-3 py-2 text-sm">
          </div>
          <div class="flex items-center gap-2 flex-wrap">
            <label class="w-[76px] shrink-0 text-sm text-gray-600">画布背景:</label>
            <input type="color" id="bgColor" value="#ffffff" class="w-9 h-9 border rounded shrink-0">
            <span class="text-xs text-gray-400 shrink-0">#ffffff</span>
          </div>
          <div class="flex items-center gap-2 flex-wrap">
            <label class="w-[76px] shrink-0 text-sm text-gray-600">填充颜色:</label>
            <input type="color" id="fillColor" value="#409EFF" class="w-9 h-9 border rounded shrink-0">
            <span class="text-xs text-gray-400 shrink-0">#409EFF</span>
          </div>
          <div class="flex items-center gap-2 flex-wrap">
            <label class="w-[76px] shrink-0 text-sm text-gray-600">线条颜色:</label>
            <input type="color" id="lineColor" value="#2563eb" class="w-9 h-9 border rounded shrink-0">
            <span class="text-xs text-gray-400 shrink-0">#2563eb</span>
          </div>
        </div>
      </div>

      <h3 class="font-semibold text-gray-700 mb-3">八大维度设置(等级:E~SSS)</h3>
      <div id="dimList" class="flex flex-col gap-2.5">
      </div>

      <button id="copyImg" class="w-full mt-5 px-4 py-2.5 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 active:bg-emerald-700 transition font-medium text-base">复制雷达图图片到剪贴板</button>
      <p class="text-xs text-gray-400 mt-2 text-center leading-normal">E不可减号|SSS不可加号|输入回车自动修正格式</p>
    </div>

    <div class="flex-1 w-full bg-white rounded-xl p-3 md:p-5 card-shadow">
      <div id="radarBox" class="w-full"></div>
    </div>
  </div>
</div>

<script>
const radarDom = document.getElementById('radarBox');
const myChart = echarts.init(radarDom);

const defaultDimNames = [
  '学习迭代', '洞察力', '长线运营', '分析思考',
  '策略精度', '心理素质', '设局能力', '信息处理'
];

const validLevels = ['E','E+','D-','D','D+','C-','C','C+','B-','B','B+','A-','A','A+','S-','S','S+','SS-','SS','SS+','SSS'];
const levelScoreMap = {
  'E':10, 'E+':18,
  'D-':26, 'D':34, 'D+':42,
  'C-':50, 'C':58, 'C+':66,
  'B-':70, 'B':75, 'B+':80,
  'A-':84, 'A':88, 'A+':92,
  'S-':94, 'S':96, 'S+':97,
  'SS-':98, 'SS':99, 'SS+':99.5,
  'SSS':100
};

let dimData = [];

function initDimItems() {
  const wrap = document.getElementById('dimList');
  wrap.innerHTML = '';
  dimData = [];
  for(let i=0;i<8;i++){
    dimData.push({name:'维度'+(i+1), level:'C'});
    const item = document.createElement('div');
    item.className = 'flex items-center gap-2 bg-gray-50 rounded px-2.5 py-2';
    item.innerHTML = `
      <input type="text" class="dim-name flex-1 border rounded px-2 py-1.5 text-sm outline-none focus:border-blue-400" placeholder="维度名称">
      <input type="text" class="dim-level level-input border rounded px-1 py-1.5 text-sm uppercase outline-none focus:border-blue-400" value="C" maxlength="4">
    `;
    wrap.appendChild(item);
  }
  bindInputEvent();
  renderChart();
}

document.getElementById('fillDefault').addEventListener('click',()=>{
  const nameInputs = document.querySelectorAll('.dim-name');
  defaultDimNames.forEach((name,idx)=>{
    nameInputs[idx].value = name;
    dimData[idx].name = name;
  })
  renderChart();
});

function formatLevel(raw) {
  let str = raw.trim().toUpperCase();
  if(str.startsWith('E') && str.includes('-')) return 'E';
  if(str === 'SSS+') return 'SSS';
  if(validLevels.includes(str)) return str;
  return 'C';
}

function bindInputEvent() {
  const nameInputs = document.querySelectorAll('.dim-name');
  const levelInputs = document.querySelectorAll('.dim-level');

  nameInputs.forEach((inp,idx)=>{
    inp.addEventListener('input',()=>{
      dimData[idx].name = inp.value.trim() || '维度'+(idx+1);
      renderChart();
    })
  });

  levelInputs.forEach((inp,idx)=>{
    inp.addEventListener('blur',()=>{
      const fix = formatLevel(inp.value);
      inp.value = fix;
      dimData[idx].level = fix;
      renderChart();
    });
    inp.addEventListener('keyup',(e)=>{
      if(e.key==='Enter') inp.blur();
    });
  });

  ['chartTitle','bgColor','fillColor','lineColor'].forEach(id=>{
    document.getElementById(id).addEventListener('input',renderChart);
  });
}

function renderChart() {
  const title = document.getElementById('chartTitle').value;
  const bg = document.getElementById('bgColor').value;
  const fill = document.getElementById('fillColor').value;
  const line = document.getElementById('lineColor').value;

  const isMobile = window.innerWidth < 768;
  const radarRadius = isMobile ? '82%' : '76%';
  const axisFontSize = isMobile ? 11 : 13;
  const titleFontSize = isMobile ? 16 : 18;

  const indicator = dimData.map(item=>({
    name: `${item.name}\n【${item.level}】`,
    max:100
  }));
  const data = dimData.map(item=>levelScoreMap[item.level]);

  const option = {
    backgroundColor: bg,
    title:{
      text: title,
      left:'center',
      textStyle:{fontSize:titleFontSize,fontWeight:500}
    },
    tooltip:{
      trigger:'item',
      formatter:(params)=>{
        const idx = params.dataIndex;
        return `${dimData[idx].name}<br>等级:${dimData[idx].level}<br>分值:${params.value}`
      }
    },
    radar:{
      radius: radarRadius,
      splitNumber:5,
      axisName:{
        fontSize: axisFontSize,
        color:'#333',
        align:'center',
        lineHeight:1.45
      },
      splitLine:{lineStyle:{color:'#e5e7eb'}},
      splitArea:{show:false},
      axisLine:{lineStyle:{color:'#d1d5db'}},
      symbol:'none',
    },
    indicator: indicator,
    series:[{
      type:'radar',
      data: data,
      areaStyle:{color: fill, opacity:0.25},
      lineStyle:{color: line, width:2},
      itemStyle:{color:line}
    }]
  };
  myChart.setOption(option);
}

function resizeChart() {
  setTimeout(()=>myChart.resize(), 120);
}
window.addEventListener('resize', resizeChart);
window.addEventListener('orientationchange', resizeChart);
window.addEventListener('blur', resizeChart);

document.getElementById('resetAll').addEventListener('click',()=>{
  const confirm1 = confirm('⚠️第一次确认:确定重置所有维度与等级数据?');
  if(!confirm1) return;
  const confirm2 = confirm('⚠️第二次确认:数据清空无法恢复,确认全部重置?');
  if(confirm2){
    document.getElementById('chartTitle').value = '个人综合能力八维雷达图';
    document.getElementById('bgColor').value = '#ffffff';
    document.getElementById('fillColor').value = '#409EFF';
    document.getElementById('lineColor').value = '#2563eb';
    initDimItems();
    alert('已完成全部重置');
  }
});

document.getElementById('copyImg').addEventListener('click',async()=>{
  try{
    const canvas = await html2canvas(radarDom,{
      backgroundColor: document.getElementById('bgColor').value,
      scale: window.innerWidth > 768 ? 2 : 1.8,
      useCORS:true,
      logging:false
    });
    canvas.toBlob(async blob=>{
      try {
        const item = new ClipboardItem({ 'image/png': blob });
        await navigator.clipboard.write([item]);
        alert('✅图片已复制剪贴板,直接粘贴即可');
      } catch (err) {
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = '八维能力雷达图.png';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        alert('⚠️浏览器剪贴板受限,已自动下载图片到相册');
      }
    })
  }catch(err){
    alert('❌复制失败:请用系统浏览器打开,不要微信内置浏览器');
    console.error(err);
  }
});

initDimItems();
</script>
</body>
</html>

Your JavaScript

-

Your CSS

-

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions