From 81493afa53a1a1d5ff4b417d05febf9f9e2a172b Mon Sep 17 00:00:00 2001 From: René 'Necoro' Neumann Date: Thu, 23 Jul 2020 00:28:47 +0200 Subject: Restructure --- kosten/static/js/kosten.js | 280 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 kosten/static/js/kosten.js (limited to 'kosten/static/js/kosten.js') diff --git a/kosten/static/js/kosten.js b/kosten/static/js/kosten.js new file mode 100644 index 0000000..3821283 --- /dev/null +++ b/kosten/static/js/kosten.js @@ -0,0 +1,280 @@ +"use strict"; + +{ + +jQuery.fn.extend({ + copy: function(){ + return this.clone().removeAttr('id class'); + } + }); + +String.prototype.splitAt = function(pos){ + return [this.slice(0, pos), this.slice(pos)]; +}; + +Date.prototype.format = function(){ + return $.datepicker.formatDate('dd.mm.yy', this); +}; + +let jq = (f) => () => $(f); + +// Call this to localize HighCharts +let setLang = function(){ + Highcharts.setOptions({ + colors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce', '#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a'], + lang: { + months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], + shortMonths: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'], + rangeSelectorFrom: 'von', + rangeSelectorTo: 'bis', + rangeSelectorZoom: null, + numericSymbols: null + } + }); +}; + +let extendDate = function(input) { + const re = /^([12][0-9]|3[01]|0?[1-9])(?:(0?[1-9]|1[0-2])((?:20)?[0-9][0-9])?)?$/; + let match, day, month, year; + + if (match = re.exec(input.val())) { + const now = new Date(); + [ , day, month, year] = match; + + if (year == null) year = now.getFullYear(); + if (month == null) month = now.getMonth() + 1; + + if (year <= 99) year = "20" + year; + + const date = new Date(year, month - 1, day).format(); + + input.val(date); + } +}; + +let searchController = function() { + $('form.search').hide(); + $('li.search').click(() => { + const search = $('form.search'); + search.toggle(); + if (search.is(':visible')) $('input.search').focus(); + }); + + $('input.search').focusout(() => $('form.search').hide()); +}; + +$(searchController); + +var showJS = jq(() => { + setLang(); + + $(".detail .heading").click(function() { + $(this).closest('.detail').children('.mark:first').click(); + }); + + $(".detail > .mark").click(function() { + if (this.src.indexOf('closed') !== -1) { + this.src = this.src.replace('closed', 'open'); + } else { + this.src = this.src.replace('open', 'closed'); + } + $(this).nextAll('.details:first').toggle(); + }); + + $('.details').hide(); + + // draw the pies + $('.pie').each(function() { + const pie = $(this); + const piedata = Object.entries(pie.data('pie')).map(([key, value]) => ( + { + name: value > 0 ? key : '', + y: value, + visible: value > 0 + })); + + pie.highcharts({ + title: { + text: null + }, + tooltip: { + hideDelay: 200, + formatter: function() { + return `${this.key}: ${this.y.toFixed(2)}€ / ${this.percentage.toFixed(2)}%`; + } + }, + chart: { + backgroundColor: null, + plotBorderWidth: null, + plotShadow: false, + spacingTop: 0 + }, + credits: { + enabled: false + }, + series: [{ + type: 'pie', + size: '70%', + states: { + hover: { + halo: null + } + }, + allowPointSelect: true, + dataLabels: { + color: pie.css('color'), + distance: 20 + }, + data: piedata + }] + }); + }); +}); + +var statJS = jq(() => { + setLang(); + + const df = Highcharts.dateFormat; + const month = 30 * 24 * 60 * 60 * 1000; + + const constDialog = function() { + const time = this.x; + + $.get(df('/stats/_const/%Y/%m', time), + data => $(data).dialog({ title: df('%B %Y', time) }) + ); + }; + + $('.stats').each(function (){ + const stats = $(this); + stats.highcharts('StockChart', { + credits: { + enabled: false + }, + rangeSelector: { + buttons: [], + inputDateFormat: "%b %Y", + inputEditDateFormat: "%m.%Y", + inputDateParser: value => { + value = value.split(/\./); + return Date.UTC( + value[1], // year + value[0] - 1, // month ... 0-based -.- + 1, // day + 0, 0, 0, 0 // time + ); + } + }, + plotOptions: { + series: { + stacking: 'normal', + marker: { + enabled: false, + radius: 2 + } + } + }, + chart: { + events: { + click: function() { + for (let point of this.series[0].data) { + if (point.state) { + // constDialog is used as a normal callback later on, so has to use 'this' + constDialog.apply(point); + break; + } + } + } + } + }, + xAxis: { + minTickInterval: month, + minRange: month + }, + yAxis: { + reversedStacks: false, + labels: { + x: 5, + align: 'left' + } + }, + series: [ + { + data: stats.data('consts'), + step: 'left', + name: 'Konstant', + point: { + events: { + click: constDialog + } + } + }, { + data: stats.data('expenses'), + name: 'Variabel', + step: 'left' + } + ], + tooltip: { + formatter: function(){ + const header = `${df('%B %Y', this.x)}
`; + const body = this.points.map(p => `${p.series.name}: ${p.point.y} €
`).join(''); + const footer = `Summe: ${this.points[0].total}`; + return header + body + footer; + } + } + }); + }); +}); + +var catsJS = jq(() => { + let counter = 0; + const addImg = $('img#add'); + const newInput = $('input#new'); + const newImage = newName => { + const copy = addImg.copy(); + copy.attr('src', function() { + return this.src.replace('add', newName); + }); + return copy; + }; + + $("li > span").click(function() { + const span = $(this); + const input = span.next(); + const img = newImage('undo'); + + img.click(function() { + $(this).remove(); + input.val(span.text()); + input.fadeOut('slow', () => span.toggle() ); + }); + + span.toggle(); + input.fadeIn('slow', () => img.insertAfter(input)); + }); + + addImg.click(() => { + const img = newImage('minus'); + img.click(function() { + $(this).parent().fadeOut('slow', function() { + $(this).remove(); + }); + }); + + const input = newInput.copy(); + console.log(input.focus); + input + .attr('name', function(){ return this.name + counter; }) + .removeAttr('style') + .wrap("
  • ") + .parent() + .append(img) + .hide() + .insertBefore(addImg.parent()) + .fadeIn('slow', () => input.focus() ); + + counter++; + }); +}); +} -- cgit v1.2.3-70-g09d2