forked from Ruderverein-Donau-Linz/rowt
		
	[WIP] typescript
This commit is contained in:
		@@ -1,85 +1,81 @@
 | 
			
		||||
import * as d3 from 'd3';
 | 
			
		||||
 | 
			
		||||
const margin = { top: 20, right: 20, bottom: 50, left: 50 },
 | 
			
		||||
width = 960 - margin.left - margin.right,
 | 
			
		||||
height = 500 - margin.top - margin.bottom;
 | 
			
		||||
export interface Data {
 | 
			
		||||
  date: Date;
 | 
			
		||||
  km: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const parseTime = d3.timeParse('%Y-%m-%d');
 | 
			
		||||
let data = [
 | 
			
		||||
  { date: new Date('2023-01-01'), km: 5 },
 | 
			
		||||
  { date: new Date('2023-02-01'), km: 24 },
 | 
			
		||||
  { date: new Date('2023-08-30'), km: 4000 },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
data.forEach((d: any) => {
 | 
			
		||||
  d.date = parseTime(d.date);
 | 
			
		||||
  d.km = +d.km;
 | 
			
		||||
});
 | 
			
		||||
if(sessionStorage.getItem('userStats')) {
 | 
			
		||||
  data = JSON.parse(sessionStorage.getItem('userStats') as Data[]);
 | 
			
		||||
 | 
			
		||||
const x = d3.scaleTime()
 | 
			
		||||
.domain(d3.extent(data, d => d.date))
 | 
			
		||||
.range([0, width]);
 | 
			
		||||
  const margin = { top: 20, right: 20, bottom: 50, left: 50 };
 | 
			
		||||
  const width: number = 960 - margin.left - margin.right;
 | 
			
		||||
  const height: number = 500 - margin.top - margin.bottom;
 | 
			
		||||
  
 | 
			
		||||
  data.forEach((d: Data) => {
 | 
			
		||||
    d.date = <Date> new Date(d.date)
 | 
			
		||||
    d.km = +d.km;
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  const x = d3.scaleTime()
 | 
			
		||||
    .domain(<[Date, Date]>d3.extent(data, (d: Data) => d.date))
 | 
			
		||||
    .range([0, width]);
 | 
			
		||||
  
 | 
			
		||||
  const y = d3.scaleLinear()
 | 
			
		||||
    .domain([0, Number(d3.max(data, (d: Data) => d.km))])
 | 
			
		||||
    .range([height, 0]);
 | 
			
		||||
  
 | 
			
		||||
  const line = d3.line<Data>()
 | 
			
		||||
    .x((d: Data) => x(d.date))
 | 
			
		||||
    .y((d: Data) => y(d.km));
 | 
			
		||||
  
 | 
			
		||||
  const svg = d3.select('#container')
 | 
			
		||||
    .append('svg')
 | 
			
		||||
    .attr('width', width + margin.left + margin.right)
 | 
			
		||||
    .attr('height', height + margin.top + margin.bottom)
 | 
			
		||||
    .call(responsivefy)
 | 
			
		||||
    .append('g')
 | 
			
		||||
    .attr('transform', `translate(${margin.left},${margin.top})`);
 | 
			
		||||
  
 | 
			
		||||
  svg.append('path')
 | 
			
		||||
    .data([data])
 | 
			
		||||
    .attr('class', 'line')
 | 
			
		||||
    .attr('d', line);
 | 
			
		||||
  
 | 
			
		||||
  svg.append('g')
 | 
			
		||||
    .attr('transform', `translate(0,${height})`)
 | 
			
		||||
    .call(d3.axisBottom(x));
 | 
			
		||||
  
 | 
			
		||||
  svg.append('g')
 | 
			
		||||
    .call(d3.axisLeft(y));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const y = d3.scaleLinear()
 | 
			
		||||
.domain([0, d3.max(data, d => d.km)])
 | 
			
		||||
.range([height, 0]);
 | 
			
		||||
 | 
			
		||||
const line = d3.line()
 | 
			
		||||
.x(d => x(d.date))
 | 
			
		||||
.y(d => y(d.km));
 | 
			
		||||
 | 
			
		||||
const svg = d3.select('#container')
 | 
			
		||||
.append('svg')
 | 
			
		||||
  .attr('width', width + margin.left + margin.right)
 | 
			
		||||
  .attr('height', height + margin.top + margin.bottom)
 | 
			
		||||
  .call(responsivefy)
 | 
			
		||||
.append('g')
 | 
			
		||||
  .attr('transform', `translate(${margin.left},${margin.top})`);
 | 
			
		||||
 | 
			
		||||
svg.append('path')
 | 
			
		||||
.data([data])
 | 
			
		||||
.attr('class', 'line')
 | 
			
		||||
.attr('d', line);
 | 
			
		||||
 | 
			
		||||
svg.append('g')
 | 
			
		||||
.attr('transform', `translate(0,${height})`)
 | 
			
		||||
.call(d3.axisBottom(x));
 | 
			
		||||
 | 
			
		||||
svg.append('g')
 | 
			
		||||
.call(d3.axisLeft(y));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function responsivefy(svg: any) {
 | 
			
		||||
  // container will be the DOM element
 | 
			
		||||
  // that the svg is appended to
 | 
			
		||||
  // we then measure the container
 | 
			
		||||
  // and find its aspect ratio
 | 
			
		||||
  const container = d3.select(svg.node().parentNode),
 | 
			
		||||
      width = parseInt(svg.style('width'), 10),
 | 
			
		||||
      height = parseInt(svg.style('height'), 10),
 | 
			
		||||
      aspect = width / height;
 | 
			
		||||
 
 | 
			
		||||
  // set viewBox attribute to the initial size
 | 
			
		||||
  // control scaling with preserveAspectRatio
 | 
			
		||||
  // resize svg on inital page load
 | 
			
		||||
  const container = d3.select(svg.node().parentNode);
 | 
			
		||||
  const width = parseInt(svg.style('width'), 10);
 | 
			
		||||
  const height = parseInt(svg.style('height'), 10);
 | 
			
		||||
  const aspect = width / height;
 | 
			
		||||
 | 
			
		||||
  svg.attr('viewBox', `0 0 ${width} ${height}`)
 | 
			
		||||
      .attr('preserveAspectRatio', 'xMinYMid')
 | 
			
		||||
      .call(resize);
 | 
			
		||||
 
 | 
			
		||||
  // add a listener so the chart will be resized
 | 
			
		||||
  // when the window resizes
 | 
			
		||||
  // multiple listeners for the same event type
 | 
			
		||||
  // requires a namespace, i.e., 'click.foo'
 | 
			
		||||
  // api docs: https://goo.gl/F3ZCFr
 | 
			
		||||
    .attr('preserveAspectRatio', 'xMinYMid')
 | 
			
		||||
    .call(resize);
 | 
			
		||||
 | 
			
		||||
  d3.select(window).on(
 | 
			
		||||
      'resize.' + container.attr('id'), 
 | 
			
		||||
      resize
 | 
			
		||||
    'resize.' + container.attr('id'),
 | 
			
		||||
    resize
 | 
			
		||||
  );
 | 
			
		||||
 
 | 
			
		||||
  // this is the code that resizes the chart
 | 
			
		||||
  // it will be called on load
 | 
			
		||||
  // and in response to window resizes
 | 
			
		||||
  // gets the width of the container
 | 
			
		||||
  // and resizes the svg to fill it
 | 
			
		||||
  // while maintaining a consistent aspect ratio
 | 
			
		||||
 | 
			
		||||
  function resize() {
 | 
			
		||||
      const w = parseInt(container.style('width'));
 | 
			
		||||
      svg.attr('width', w);
 | 
			
		||||
      svg.attr('height', Math.round(w / aspect));
 | 
			
		||||
    const w = parseInt(container.style('width'));
 | 
			
		||||
    svg.attr('width', w);
 | 
			
		||||
    svg.attr('height', Math.round(w / aspect));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -43,6 +43,7 @@ const data = [
 | 
			
		||||
    { date: '{{p.date}}', km: {{p.km}} },
 | 
			
		||||
  {%- endfor %}
 | 
			
		||||
]
 | 
			
		||||
sessionStorage.setItem('userStats', JSON.stringify(data));
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script src="/public/logbook.js"></script>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user