Skip to content

八维 #2426

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions