首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用onchange滑块事件更新d3图表中的数据?

如何使用onchange滑块事件更新d3图表中的数据?
EN

Stack Overflow用户
提问于 2021-02-28 19:31:42
回答 1查看 132关注 0票数 1

附件是我在JS中的最小工作示例。我只能显示初始数据,但当我更改滑块时,数据不会更新。在这里,我的代码哪里出错了?对于糟糕的结构,我很抱歉--我仍然是D3的初学者。

https://jsfiddle.net/pv02z8em/1/

代码语言:javascript
复制
chartGroup
    .selectAll('.line-series')
    .data(data, d=> d.x)
    .join(
      enter => {
        enter.append('path')
        .attr('class', d => `line-series x_${d.x}`)
        .attr("d", drawLine(data))
        .style('stroke', 'dodgerblue')
        .style('stroke-width', 2)
        .style('fill', 'none')
        .style('opacity', 1)
      },
      update => { update.transition().duration(500) },
      exit => { exit.remove() }
    )
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-28 20:13:50

您在该代码中有几个问题:

您没有根据滑块的ID选择滑块。滑块应该是

在侦听器中,您不会调用

移走里面的所有东西

这与路径本身无关,否则每次用户移动滑块时都会创建不同的SVG;

你的

结构当前正在追加

几个

路径,一个在另一个之上。这肯定不是你想要的。它可能只是:

让path = chartGroup.selectAll('.line-series') .data(

数据

);path = path.enter() .append(‘路径’).attr(‘类’,“线条系列”) .attr("d",d => drawLine(d)) .style(‘描边’,‘渐变蓝’).style(‘描边宽度’,2) .style(‘填充’,‘无’).style(‘不透明度’,1) .merge(path) path.transition().duration(500).attr("d",d => drawLine(d))

以下是您的代码,其中包含这些和其他细微更改:

代码语言:javascript
复制
svg {
        display: inline-block;
        position: relative;
        vertical-align: top;
        overflow: hidden;

      }

      .x-axis,
      .y-axis {
        font: 16px sans-serif;
      }

      .axis-label {
        font: 18px sans-serif;
      }

      .chart-title {
        font: 24px sans-serif;
      }

      .x-axis .tick:first-of-type text {
        fill: none;
      }

      .body {
        display: flex;
      }

      .chart-group-container {
        margin: 10px 20px 20px 20px;
      }

      .controls-container {
        display: flex;
        flex-direction: column;
      }

      .controls-header {
        color: black;
        padding: 0.5rem 2rem;
        text-align: left;

      }

      .controls-body {
        overflow: auto;
        font-size: 0.8em;
        cursor: default;
      }

      .slidecontainer {
        text-align: left;
        margin: 10px;
        font-family: sans-serif;
        font-size: 14px;
      }

      #slider-x-range {
        vertical-align: bottom;
      }

    
    Document
  

  
    
      
        
          
            

            
          
        
        
        
          UI Controls
          
            Adjust x axis
            
              10
              
              100
            

          
        
      


      
      
        //let sinWave = Math.sin(x)

        let range = function(start, stop, step) {
          step = step || 1;
          let arr = []
          for (let i = start; i < stop; i += step) {
            arr.push(i);
          }
          return arr;
        }

        let generateSinWave = function(x) {
          let y = []
          x.forEach(function(i) {
            y.push(Math.sin(i))
          });
          return y;
        }

        const generateData = (n) => {
          x = range(0, n, 1)
          y = generateSinWave(x)

          let labels = ['x', 'y']

          let data = []
          for (let i = 0; i < x.length; i++) {
            data.push({
              x: x[i],
              y: y[i]
            })
          }
          return data;
        }

      
      
        let margin = {
            top: 50,
            right: 30,
            bottom: 30,
            left: 100
          },
          width = 800 - margin.left - margin.right
        height = 400 - margin.top - margin.bottom;

        let xScale = d3.scaleLinear()
          .range([0, width])

        let yScale = d3.scaleLinear()
          .range([height, 0])
          .nice()


        let drawLine = d3.line()
          .x(d => xScale(d.x))
          .y(d => yScale(d.y))
          .curve(d3.curveBasis);


        let svg = d3.select('.viz')
          .append('svg')
          .attr("viewBox", `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`)
          .attr("preserveAspectRatio", "xMinYMin meet")
          //.attr('width', `${width + margin.left + margin.right}px`)
          //.attr('height', `${height + margin.top + margin.bottom}px`)
          //.classed("svg-content", true);
          .append('g')
          .attr('class', 'line-chart-container')
          .attr('transform', `translate(${margin.left}, ${margin.top})`);

        /* d3.select(".line-chart-container")
                  .attr("style", "outline: thin solid black;") 
                  .attr("margin-right", "102px") */



        const chartGroup = svg.append('g').attr('class', 'line-chart')

        // Draw x axis
        const xAxis = d3.axisBottom(xScale).tickSizeOuter(0);

        const xAxisDraw = svg
          .append('g')
          .attr('class', 'x-axis')
          //.style('font', '14px sans-serif')
          .attr('transform', `translate(0, ${height / 2})`)
          .call(xAxis);

        const yAxis = d3
          .axisLeft(yScale)
          .ticks(10)
        //.tickSizeInner(-width);

        const yAxisDraw = svg
          .append('g')
          .attr('class', 'y-axis')
          .call(yAxis);

        // x axis label
        svg.append('text')
          .attr('class', 'axis-label')
          .attr('text-anchor', 'end')
          .text('X axis')
          .attr('x', width)
          .attr('y', height - margin.bottom + 50)

        // y axis label
        svg.append('text')
          .attr('class', 'axis-label')
          .attr('text-anchor', 'end')
          .attr('transform', 'rotate(-90)')
          .attr('x', margin.top + 50 - (height / 2))
          .attr('y', margin.left - 160)
          .text('Y axis')

        // Draw Header
        const header = svg
          .append('g')
          .attr('class', 'chart-title')
          .attr('transform', `translate(${width / 2 - 75}, ${margin.top - 75})`)
          .append('text')

        header.append('tspan').text('Sine wave')

        function buildLine(data) {

          xScale.domain([d3.min(data, d => d.x), d3.max(data, d => d.x)])

          yScale.domain([d3.min(data, d => d.y), d3.max(data, d => d.y)])

          let path = chartGroup
            .selectAll('.line-series')
            .data([data]);

          path = path.enter().append('path')
            .attr('class', "line-series")
            .attr("d", d => drawLine(d))
            .style('stroke', 'dodgerblue')
            .style('stroke-width', 2)
            .style('fill', 'none')
            .style('opacity', 1)
            .merge(path)

          path.transition().duration(500).attr("d", d => drawLine(d))
        }

        let xRangeSlider = document.getElementById('slider-x-range');
        xRangeSlider.min = 10;
        xRangeSlider.max = 100;

        let data = generateData(xRangeSlider.value)

        buildLine(data)

        d3.select('#slider-x-range')
          .on("change", d => {
            data = generateData(xRangeSlider.value)
            buildLine(data)
          });

正如您将发现的那样,转换可能不是您所期望的:这是一个无关的问题,即

属性字符串(您可以找到更多信息

这里

)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66408600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档