diff --git a/public/js/ff/charts.js b/public/js/ff/charts.js index bec7c03c18..ac1c391d94 100644 --- a/public/js/ff/charts.js +++ b/public/js/ff/charts.js @@ -58,49 +58,6 @@ Chart.defaults.global.animation.duration = 0; Chart.defaults.global.responsive = true; Chart.defaults.global.maintainAspectRatio = false; - -/** - * Chart line thing - */ -const verticalLinePlugin = { - getLinePosition: function (chart, pointIndex) { - const meta = chart.getDatasetMeta(0); // first dataset is used to discover X coordinate of a point - const data = meta.data; - return data[pointIndex]._model.x; - }, - renderVerticalLine: function (chartInstance, pointIndex) { - const lineLeftOffset = this.getLinePosition(chartInstance, pointIndex); - const scale = chartInstance.scales['y-axis-0']; - const context = chartInstance.chart.ctx; - - // render vertical line - context.beginPath(); - context.strokeStyle = fillColors[3]; - context.moveTo(lineLeftOffset, scale.top); - context.lineTo(lineLeftOffset, scale.bottom); - context.stroke(); - - // write label - context.fillStyle = "#444444"; - context.textAlign = 'left'; - if(pointIndex > 23) { - todayText = todayText + ' '; - context.textAlign = 'right'; - } - context.fillText(todayText, lineLeftOffset, scale.top * 3); // (scale.bottom - scale.top) / 2 + scale.top - }, - - afterDatasetsDraw: function (chart, easing) { - if (chart.config.lineAtIndex) { - chart.config.lineAtIndex.forEach(function(pointIndex) { - this.renderVerticalLine(chart, pointIndex); - }, this); - } - } -}; - -Chart.plugins.register(verticalLinePlugin); - /** * * @param data @@ -132,16 +89,7 @@ function lineChart(URI, container) { var options = $.extend(true, {}, defaultChartOptions); var chartType = 'line'; - drawAChart(URI, container, chartType, options, colorData, -1); -} - -function lineChartWithDay(URI, container, today) { - "use strict"; - var colorData = true; - var options = $.extend(true, {}, defaultChartOptions); - var chartType = 'line'; - - drawAChart(URI, container, chartType, options, colorData, today); + drawAChart(URI, container, chartType, options, colorData); } /** @@ -302,7 +250,7 @@ function pieChart(URI, container) { * @param colorData * @param today */ -function drawAChart(URI, container, chartType, options, colorData, today) { +function drawAChart(URI, container, chartType, options, colorData) { var containerObj = $('#' + container); if (containerObj.length === 0) { return; @@ -343,10 +291,34 @@ function drawAChart(URI, container, chartType, options, colorData, today) { type: chartType, data: data, options: options, - lineAtIndex: [] + lineAtIndex: [], + annotation: {}, }; - if (today >= 0) { - chartOpts.lineAtIndex.push(today - 1); + if (drawVerticalLine !== '') { + // draw line using annotation plugin. + console.log('Will draw line'); + chartOpts.options.annotation = { + annotations: [{ + type: 'line', + id: 'a-line-1', + mode: 'vertical', + scaleID: 'x-axis-0', + value: drawVerticalLine, + borderColor: 'red', + borderWidth: 1, + label: { + backgroundColor: 'rgba(0,0,0,0)', + fontFamily: "sans-serif", + fontSize: 12, + fontColor: "#333", + position: "right", + xAdjust: 0, + yAdjust: -120, + enabled: true, + content: todayText + } + }] + }; } allCharts[container] = new Chart(ctx, chartOpts); } diff --git a/public/js/ff/index.js b/public/js/ff/index.js index a5698cea55..88b15cfccb 100644 --- a/public/js/ff/index.js +++ b/public/js/ff/index.js @@ -29,11 +29,7 @@ $(function () { function drawChart() { "use strict"; - if (today >= 0) { - lineChartWithDay(accountFrontpageUri, 'accounts-chart', today); - } else { - lineChart(accountFrontpageUri, 'accounts-chart'); - } + lineChart(accountFrontpageUri, 'accounts-chart'); if (billCount > 0) { pieChart('chart/bill/frontpage', 'bills-chart'); diff --git a/public/js/lib/chartjs-plugin-annotation.min.js b/public/js/lib/chartjs-plugin-annotation.min.js new file mode 100755 index 0000000000..ec326acf55 --- /dev/null +++ b/public/js/lib/chartjs-plugin-annotation.min.js @@ -0,0 +1,10 @@ +/*! + * chartjs-plugin-annotation.js + * http://chartjs.org/ + * Version: 0.5.7 + * + * Copyright 2016 Evert Timberg + * Released under the MIT license + * https://github.com/chartjs/Chart.Annotation.js/blob/master/LICENSE.md + */ +!function e(t,n,i){function o(r,l){if(!n[r]){if(!t[r]){var s="function"==typeof require&&require;if(!l&&s)return s(r,!0);if(a)return a(r,!0);var c=new Error("Cannot find module '"+r+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[r]={exports:{}};t[r][0].call(u.exports,function(e){var n=t[r][1][e];return o(n?n:e)},u,u.exports,e,t,n,i)}return n[r].exports}for(var a="function"==typeof require&&require,r=0;r0){var n=e.chart.canvas,i=r.dispatcher.bind(e);r.collapseHoverEvents(t).forEach(function(t){o.addEvent(n,t,i),e.annotation.onDestroy.push(function(){o.removeEvent(n,t,i)})})}},destroy:function(e){for(var t=e.annotation.onDestroy;t.length>0;)t.pop()()}}}},{"./events.js":4,"./helpers.js":5}],3:[function(e,t,n){t.exports=function(e){var t=e.helpers,n=e.Element.extend({initialize:function(){this.hidden=!1,this.hovering=!1,this._model=t.clone(this._model)||{},this.setDataLimits()},destroy:function(){},setDataLimits:function(){},configure:function(){},inRange:function(){},getCenterPoint:function(){},getWidth:function(){},getHeight:function(){},getArea:function(){},draw:function(){}});return n}},{}],4:[function(e,t,n){t.exports=function(t){function n(e){var t=!1,n=e.filter(function(e){switch(e){case"mouseenter":case"mouseover":case"mouseout":case"mouseleave":return t=!0,!1;default:return!0}});return t&&n.indexOf("mousemove")===-1&&n.push("mousemove"),n}function i(e){var t=this.annotation,i=a.elements(this),r=o.getRelativePosition(e,this.chart),l=a.getNearestItems(i,r),s=n(t.options.events),c=t.options.dblClickSpeed,u=[],f=a.getEventHandlerName(e.type),d=(l||{}).options;if("mousemove"===e.type&&(l&&!l.hovering?["mouseenter","mouseover"].forEach(function(t){var n=a.getEventHandlerName(t),i=a.createMouseEvent(t,e);l.hovering=!0,"function"==typeof d[n]&&u.push([d[n],i,l])}):l||i.forEach(function(t){if(t.hovering){t.hovering=!1;var n=t.options;["mouseout","mouseleave"].forEach(function(i){var o=a.getEventHandlerName(i),r=a.createMouseEvent(i,e);"function"==typeof n[o]&&u.push([n[o],r,t])})}})),l&&s.indexOf("dblclick")>-1&&"function"==typeof d.onDblclick){if("click"===e.type&&"function"==typeof d.onClick)return clearTimeout(l.clickTimeout),l.clickTimeout=setTimeout(function(){delete l.clickTimeout,d.onClick.call(l,e)},c),e.stopImmediatePropagation(),void e.preventDefault();"dblclick"===e.type&&l.clickTimeout&&(clearTimeout(l.clickTimeout),delete l.clickTimeout)}l&&"function"==typeof d[f]&&0===u.length&&u.push([d[f],e,l]),u.length>0&&(e.stopImmediatePropagation(),e.preventDefault(),u.forEach(function(e){e[0].call(e[2],e[1])}))}var o=t.helpers,a=e("./helpers.js")(t);return{dispatcher:i,collapseHoverEvents:n}}},{"./helpers.js":5}],5:[function(e,t,n){function i(){}function o(e){var t=e.annotation.elements;return Object.keys(t).map(function(e){return t[e]})}function a(){return Math.random().toString(36).substr(2,6)}function r(e){return null!==e&&"undefined"!=typeof e&&("number"==typeof e?isFinite(e):!!e)}function l(e,t,n){var i="$";e[i+t]||(e[t]?(e[i+t]=e[t].bind(e),e[t]=function(){var o=[e[i+t]].concat(Array.prototype.slice.call(arguments));return n.apply(e,o)}):e[t]=function(){var t=[void 0].concat(Array.prototype.slice.call(arguments));return n.apply(e,t)})}function s(e,t){e.forEach(function(e){(t?e[t]:e)()})}function c(e){return"on"+e[0].toUpperCase()+e.substring(1)}function u(e,t){try{return new MouseEvent(e,t)}catch(n){try{var i=document.createEvent("MouseEvent");return i.initMouseEvent(e,t.canBubble,t.cancelable,t.view,t.detail,t.screenX,t.screenY,t.clientX,t.clientY,t.ctrlKey,t.altKey,t.shiftKey,t.metaKey,t.button,t.relatedTarget),i}catch(o){var a=document.createEvent("Event");return a.initEvent(e,t.canBubble,t.cancelable),a}}}t.exports=function(e){function t(t){return t=h.configMerge(e.Annotation.defaults,t),h.isArray(t.annotations)&&t.annotations.forEach(function(t){t.label=h.configMerge(e.Annotation.labelDefaults,t.label)}),t}function n(e,t,n,i){var o=t.filter(function(t){return!!t._model.ranges[e]}).map(function(t){return t._model.ranges[e]}),a=o.map(function(e){return Number(e.min)}).reduce(function(e,t){return isFinite(t)&&!isNaN(t)&&te?t:e},i);return{min:a,max:r}}function f(e){var t=n(e.id,o(e.chart),e.min,e.max);"undefined"==typeof e.options.ticks.min&&"undefined"==typeof e.options.ticks.suggestedMin&&(e.min=t.min),"undefined"==typeof e.options.ticks.max&&"undefined"==typeof e.options.ticks.suggestedMax&&(e.max=t.max),e.handleTickRangeOptions&&e.handleTickRangeOptions()}function d(e,t){var n=Number.POSITIVE_INFINITY;return e.filter(function(e){return e.inRange(t.x,t.y)}).reduce(function(e,i){var o=i.getCenterPoint(),a=h.distanceBetweenPoints(t,o);return ai||n=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom},getCenterPoint:function(){var e=this._model;return{x:(e.right+e.left)/2,y:(e.bottom+e.top)/2}},getWidth:function(){var e=this._model;return Math.abs(e.right-e.left)},getHeight:function(){var e=this._model;return Math.abs(e.bottom-e.top)},getArea:function(){return this.getWidth()*this.getHeight()},draw:function(){var e=this._view,t=this.chartInstance.chart.ctx;t.save(),t.beginPath(),t.rect(e.clip.x1,e.clip.y1,e.clip.x2-e.clip.x1,e.clip.y2-e.clip.y1),t.clip(),t.lineWidth=e.borderWidth,t.strokeStyle=e.borderColor,t.fillStyle=e.backgroundColor;var n=e.right-e.left,i=e.bottom-e.top;t.fillRect(e.left,e.top,n,i),t.strokeRect(e.left,e.top,n,i),t.restore()}});return i}},{"../helpers.js":5}],8:[function(e,t,n){t.exports=function(t){function n(e){var t=(e.x2-e.x1)/(e.y2-e.y1),n=e.x1||0;this.m=t,this.b=n,this.getX=function(i){return t*(i-e.y1)+n},this.getY=function(i){return(i-n)/t+e.y1},this.intersects=function(e,t,n){n=n||.001;var i=this.getY(e),o=this.getX(t);return(!isFinite(i)||Math.abs(t-i)=n.labelX&&e<=n.labelX+n.labelWidth&&t>=n.labelY&&t<=n.labelY+n.labelHeight},getCenterPoint:function(){return{x:(this._model.x2+this._model.x1)/2,y:(this._model.y2+this._model.y1)/2}},getWidth:function(){return Math.abs(this._model.right-this._model.left)},getHeight:function(){return this._model.borderWidth||1},getArea:function(){return Math.sqrt(Math.pow(this.getWidth(),2)+Math.pow(this.getHeight(),2))},draw:function(){var e=this._view,t=this.chartInstance.chart.ctx;e.clip&&(t.save(),t.beginPath(),t.rect(e.clip.x1,e.clip.y1,e.clip.x2-e.clip.x1,e.clip.y2-e.clip.y1),t.clip(),t.lineWidth=e.borderWidth,t.strokeStyle=e.borderColor,t.setLineDash&&t.setLineDash(e.borderDash),t.lineDashOffset=e.borderDashOffset,t.beginPath(),t.moveTo(e.x1,e.y1),t.lineTo(e.x2,e.y2),t.stroke(),e.labelEnabled&&e.labelContent&&(t.beginPath(),t.rect(e.clip.x1,e.clip.y1,e.clip.x2-e.clip.x1,e.clip.y2-e.clip.y1),t.clip(),t.fillStyle=e.labelBackgroundColor,o.drawRoundedRectangle(t,e.labelX,e.labelY,e.labelWidth,e.labelHeight,e.labelCornerRadius),t.fill(),t.font=o.fontString(e.labelFontSize,e.labelFontStyle,e.labelFontFamily),t.fillStyle=e.labelFontColor,t.textAlign="center",t.textBaseline="middle",t.fillText(e.labelContent,e.labelX+e.labelWidth/2,e.labelY+e.labelHeight/2)),t.restore())}});return s}},{"../helpers.js":5}]},{},[6]); \ No newline at end of file diff --git a/resources/views/index.twig b/resources/views/index.twig index 32abc8fa8b..ca085b5163 100644 --- a/resources/views/index.twig +++ b/resources/views/index.twig @@ -189,16 +189,15 @@ var accountExpenseUri = '{{ route('chart.account.expense') }}'; var piggyInfoUri = '{{ route('json.fp.piggy-banks') }}'; var todayText = ' {{ trans('firefly.today')|escape('js') }}'; - + var drawVerticalLine = ''; {# render vertical line with text "today" #} {% if start.lte(today) and end.gte(today) %} - var today = {{ today.diffInDays(start) + 1 }}; - {% else %} - var today = -1; + drawVerticalLine = '{{ today.formatLocalized(monthAndDayFormat) }}'; {% endif %} +