You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双独立下拉选择框联动更新对应UFC选手KD图表的实现问题

问题核心原因

当前代码存在4个直接导致第二个下拉框联动失效的问题:

  • 第二个下拉框绑定的onchange事件触发optionsChanged函数,但代码中从未定义该函数,触发时会直接抛出函数未定义的引用错误
  • 现有visuals绘图函数硬编码了渲染目标为id=bar的容器,就算第二个下拉框能触发回调,图表也只会覆盖第一个卡片的内容,不会渲染到第二个卡片的bar2容器
  • optionChanged回调里每次触发都重复调用init,会导致下拉框选项被重复追加,产生冗余选项
  • 初始化逻辑仅完成了下拉选项渲染,没有在页面首次加载时触发第二个图表的默认渲染
修复方案

1. 改造通用绘图函数,支持指定渲染容器

复用现有绘图逻辑,新增容器入参,避免写两套重复的绘图代码,修改后的visuals函数如下:

/**
 * 渲染选手KD历史数据图表
 * @param {string} fighter 选中的选手名称
 * @param {string} containerId 图表挂载的DOM容器ID,默认渲染到第一个卡片的bar容器
 */
function visuals(fighter, containerId = 'bar'){
  console.log('selected fighter: ', fighter)
  d3.json(`http://127.0.0.1:5000/combined/${fighter}`).then( data => { 
    const combinedData = data;
    const dateList = [];
    const kdList = [];

    for(let i = 0; i < combinedData.length; i++) {
      kdList.push(combinedData[i].avg_KD);
      dateList.push(combinedData[i].date);
    }

    const plotData = [
      {
        x: dateList,
        y: kdList,
        type: 'histogram',
        marker: {
          color: '#C70039',
          line: {
            color:  "rgba(255, 100, 102, 1)",
            width: 1
          }
        },
      }
    ];
    const barLayout= {
      title: 'KD History',
      hovermode: "closest",
      xaxis: {title: 'Date'},
      yaxis: {title:'KD'},
      margin: {t:30}
    };
    // 将图表渲染到指定容器
    Plotly.newPlot(containerId, plotData, barLayout);
  });
}

2. 补全两个下拉框的变更回调

拆分两个下拉框的触发逻辑,分别对应渲染到两个图表容器,移除无意义的重复init调用:

// 第一个下拉框变更回调:渲染到第一个卡片的bar容器
function optionChanged(fighter) {
  visuals(fighter, 'bar');
  // 如需更新第一个卡片的选手元数据,在此处添加对应逻辑即可
}

// 第二个下拉框变更回调:渲染到第二个卡片的bar2容器
function optionsChanged(fighter) {
  visuals(fighter, 'bar2');
  // 如需更新第二个卡片的选手元数据,在此处添加对应逻辑即可
}

3. 优化初始化逻辑

修改init函数,完成下拉选项渲染后自动加载默认选手的两个图表,避免重复渲染下拉选项:

function init() {
  d3.json("http://127.0.0.1:5000/fighters").then(fighterList => {
    // 渲染第一个下拉框选项
    const dropdown1 = d3.select("#selDataset");
    fighterList.forEach(fighterName => {
      dropdown1.append('option').text(fighterName)
    })

    // 渲染第二个下拉框选项
    const dropdown2 = d3.select("#selDataset1");
    fighterList.forEach(fighterName => {
      dropdown2.append('option').text(fighterName)
    })

    // 设置默认选中选手(默认取列表第一位)
    const defaultFighter = fighterList[0];
    dropdown1.property('value', defaultFighter);
    dropdown2.property('value', defaultFighter);
    
    // 首次加载渲染两个默认图表
    optionChanged(defaultFighter);
    optionsChanged(defaultFighter);
  });
}

// 页面加载完成后执行初始化
init();

4. 确认HTML绑定配置

现有HTML的下拉框事件绑定无需修改,确认对应关系即可:

  • 第一个下拉框id="selDataset"绑定onchange="optionChanged(this.value)",对应渲染id="bar"的图表容器
  • 第二个下拉框id="selDataset1"绑定onchange="optionsChanged(this.value)",对应渲染id="bar2"的图表容器
注意事项
  • 确保存放回调函数、初始化逻辑的JS文件,在存放visuals绘图函数的JS文件之后引入,避免出现「visuals未定义」的报错
  • 如果需要区分两个图表的样式、标题,只需要给visuals函数新增对应的配置入参即可,无需重复编写两套绘图逻辑
  • 必须移除原来optionChanged函数里调用init()的逻辑,否则每次切换下拉选项都会重复追加下拉选项,造成选项冗余。

内容的提问来源于stack exchange,提问作者Immanuel Nii Odai Odarteifio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:21:33