[WIP] typescript
This commit is contained in:
		| @@ -1,85 +1,81 @@ | |||||||
| import * as d3 from 'd3'; | import * as d3 from 'd3'; | ||||||
|  |  | ||||||
| const margin = { top: 20, right: 20, bottom: 50, left: 50 }, | export interface Data { | ||||||
| width = 960 - margin.left - margin.right, |   date: Date; | ||||||
| height = 500 - margin.top - margin.bottom; |   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) => { | if(sessionStorage.getItem('userStats')) { | ||||||
|   d.date = parseTime(d.date); |   data = JSON.parse(sessionStorage.getItem('userStats') as Data[]); | ||||||
|   d.km = +d.km; |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const x = d3.scaleTime() |   const margin = { top: 20, right: 20, bottom: 50, left: 50 }; | ||||||
| .domain(d3.extent(data, d => d.date)) |   const width: number = 960 - margin.left - margin.right; | ||||||
| .range([0, width]); |   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) { | function responsivefy(svg: any) { | ||||||
|   // container will be the DOM element |   const container = d3.select(svg.node().parentNode); | ||||||
|   // that the svg is appended to |   const width = parseInt(svg.style('width'), 10); | ||||||
|   // we then measure the container |   const height = parseInt(svg.style('height'), 10); | ||||||
|   // and find its aspect ratio |   const aspect = width / height; | ||||||
|   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 |  | ||||||
|   svg.attr('viewBox', `0 0 ${width} ${height}`) |   svg.attr('viewBox', `0 0 ${width} ${height}`) | ||||||
|       .attr('preserveAspectRatio', 'xMinYMid') |     .attr('preserveAspectRatio', 'xMinYMid') | ||||||
|       .call(resize); |     .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 |  | ||||||
|   d3.select(window).on( |   d3.select(window).on( | ||||||
|       'resize.' + container.attr('id'),  |     'resize.' + container.attr('id'), | ||||||
|       resize |     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() { |   function resize() { | ||||||
|       const w = parseInt(container.style('width')); |     const w = parseInt(container.style('width')); | ||||||
|       svg.attr('width', w); |     svg.attr('width', w); | ||||||
|       svg.attr('height', Math.round(w / aspect)); |     svg.attr('height', Math.round(w / aspect)); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -43,6 +43,7 @@ const data = [ | |||||||
|     { date: '{{p.date}}', km: {{p.km}} }, |     { date: '{{p.date}}', km: {{p.km}} }, | ||||||
|   {%- endfor %} |   {%- endfor %} | ||||||
| ] | ] | ||||||
|  | sessionStorage.setItem('userStats', JSON.stringify(data)); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <script src="/public/logbook.js"></script> | <script src="/public/logbook.js"></script> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Marie Birner
					Marie Birner