如何处理d3 v4响应折线图?

时间:2018-03-07 17:35:35

标签: javascript html d3.js responsive-design

感谢您查看此内容! 当前:我有一个半响应的折线图。 目标:在窗口重新调整大小时获取要更新的行(路径)。

这是一个小提琴

https://jsfiddle.net/nfpjwyoz/9/

注意: - 我正在使用D3 v4。

  • 加载的数据是一个简单的csv,如...

年,人口

1950,228670

1951,233277

1952,238113

  • 我遇到困难的调整大小部分是“更新线路”'节

任何帮助?! 谢谢!



const xLabel = 'Year';
const yLabel = 'Population';

const xValue = d => d.year;
const yValue = d => d.population;

const margin = {
  left: 140,
  right: 50,
  top: 50,
  bottom: 120
};

//Select/Create div, svg, g
const chartDiv = document.getElementById('chartDiv');
const svgObj = d3.select(chartDiv).append("svg").attr("border", '2px solid green');
const gObj = svgObj.append('g').attr('class', 'gWrapper');

//Setup Scales
const xScale = d3.scaleTime();
const yScale = d3.scaleLinear();

// Extract the DIV width and height that was computed by CSS.
let parentDivWidth = chartDiv.clientWidth;
let parentDivHeight = chartDiv.clientHeight;

//get css-computed dimensions
const divWidthLessMargins = parentDivWidth - margin.left - margin.right;
const divHeightLessMargins = parentDivHeight - margin.top - margin.bottom;

//set svg height & width from div computed dimensions
//NOTE: can be the divLessMargins, for 'padding' effect
svgObj.attrs({
  "width": parentDivWidth,
  "height": parentDivHeight
});

//translate the gWrapper
gObj.attr('transform', `translate(${margin.left},${margin.top})`);

//Build Axis Groups
const xAxisG = gObj.append('g')
  .attrs({
    'transform': `translate(0, ${divHeightLessMargins})`,
    'class': 'axis x'
  });
const yAxisG = gObj.append('g')
  .attrs({
    'class': 'axis y',
    // 'transform': `rotate(-90)`
  });

//set placeholder for axis labels      
let xAxisLabel = xAxisG.append('text');
let yAxisLabel = yAxisG.append('text');

//set attrs for axis labels      
xAxisLabel
  .attrs({
    'class': 'axis-label',
    'x': (divWidthLessMargins / 2),
    'y': '100'
  })
  .text(xLabel);

yAxisLabel
  .attrs({
    'class': 'axis-label',
    'x': -divHeightLessMargins / 2,
    'y': -margin.left / 1.5,
    'transform': `rotate(-90)`
  })
  .style('text-anchor', 'middle')
  .text(yLabel);

//Build Axis elements
const xAxis = d3.axisBottom()
  .scale(xScale)
  .tickPadding(15)
  .tickSize(-divWidthLessMargins);

const yAxis = d3.axisLeft()
  .scale(yScale)
  .ticks(5)
  .tickPadding(15)
  .tickFormat(d3.format('.1s'))
  .tickSize(-divWidthLessMargins);

const lineObj = d3.line()
  .x(d => xScale(xValue(d)))
  .y(d => yScale(yValue(d)))
  .curve(d3.curveBasis)

const parseData = d => {
  d.population = +d.population;
  // let format = d3.format("%s");
  // d.formPop = format(d.population);
  let parsedDate = d3.timeParse("%Y");
  d.year = parsedDate(d.year);
  return d;
};

function buildChart(obj) {

  d3.csv(obj.dataFile, parseData, data => {
    xScale
      .domain(d3.extent(data, xValue))
      .range([0, divWidthLessMargins]);

    yScale
      .domain(d3.extent(data, yValue))
      .range([divHeightLessMargins, margin.top])
      .nice();

    gObj.append('path')
      .attrs({
        'fill': 'none',
        'stroke': 'steelblue',
        'stroke-width': 4,
        'class': 'path',
        'd': lineObj(data)
      });

    xAxisG.call(xAxis)
      .selectAll('.tick line').attrs({
        'class': 'xLine',
        'stroke-dasharray': '1, 5'
      });

    xAxisG.selectAll('.tick text')
      .attrs({
        'transform': 'rotate(-45)',
        'text-anchor': 'end',
        'alignment-baseline': 'middle',
        'x': -5,
        'y': 15,
        'dy': 0
      })

    yAxisG.call(yAxis)
      .selectAll('.tick line').attrs({
        'class': 'yLine',
        'stroke-dasharray': '1, 5'
      });

  });

}

let AllChartObj = {
  svgClass: '.svgWrapper',
  dataFile: 'data.csv'
}
buildChart(AllChartObj);

//2. Build fn
let resize = () => {

  // Extract the width and height that was computed by CSS.
  let resizedFnWidth = chartDiv.clientWidth;
  let resizedFnHeight = chartDiv.clientHeight;

  //set svg dimension based on resizing attrs
  svgObj.attrs({
    "width": resizedFnWidth,
    "height": resizedFnHeight
  });

  //calc resized dimensions less margins
  let resizedWidthLessMargins = resizedFnWidth - margin.left - margin.right;
  let resizedHeightLessMargins = resizedFnHeight - margin.top - margin.bottom;

  //update scale ranges
  xScale.range([0, resizedWidthLessMargins]);
  yScale.range([resizedHeightLessMargins, margin.top]);

  //Update the line
  let grabbedLine = d3.selectAll('path');
  console.log('grabbedLine ->', grabbedLine);

  d3.selectAll(grabbedLine)
    .attr("d", d => lineObj(d));


  //Update the X-AXIS
  xAxisG
    .attrs({
      'transform': `translate(0, ${resizedHeightLessMargins})`,
      'x': divWidthLessMargins / 2,
      'y': resizedFnHeight * .1,
    })
    .call(xAxis);

  //Update the X-AXIS LABEL
  xAxisLabel
    .attrs({
      'x': resizedWidthLessMargins / 2
    })

  //Update the Y-AXIS
  yAxisG
    .attrs({
      'x': -resizedHeightLessMargins / 2,
      'y': -margin.left / 2,
    })
    .call(yAxis);

  //Update yAxis Label
  yAxisLabel.attrs({
    'x': -resizedHeightLessMargins / 2,
    'y': -margin.left / 1.5,
  });

  //update yLines
  d3.selectAll('.yLine')
    .attr('x2', resizedWidthLessMargins);

}

//1. Add Resise listener & fn call
d3.select(window).on('resize', resize);
// resize();

* {
  box-sizing: border-box;
}

body {
  margin: 0px;
  background-color: rgba(0, 0, 0, .75);
  font-family: sans-serif;
}

#chartDiv {
  position: absolute;
  left: 0px;
  right: 0px;
  top: 0px;
  bottom: 0px;
}

.domain {
  display: none;
}

.tick line {
  stroke: #C0C0BB;
}

.tick text,
.legendCells text {
  fill: #8E8883;
  font-size: 28pt;
  font-family: sans-serif;
}

.axis-label,
.legend-label {
  fill: #635F5D;
  font-size: 20pt;
  font-family: sans-serif;
}

<!DOCTYPE html>
<html>

<head>
  <title>Responsive Line</title>
</head>

<body>
  <meta charset="utf-8">
  <meta content="width=device-width" name="viewport">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js">
  </script>
  <script src="https://d3js.org/d3-selection-multi.v1.min.js">
  </script>
  <div id="chartDiv"></div>
</body>

</html>
&#13;
&#13;
&#13;

0 个答案:

没有答案