diff --git a/frappe/hooks.py b/frappe/hooks.py index 707b2fac37..749132cba8 100755 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -30,7 +30,6 @@ app_include_js = [ "assets/js/form.min.js", "assets/js/control.min.js", "assets/js/report.min.js", - "assets/js/d3.min.js", "assets/frappe/js/frappe/toolbar.js" ] app_include_css = [ diff --git a/frappe/public/build.json b/frappe/public/build.json index 8896b85685..56f1b21f25 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -102,7 +102,6 @@ "public/css/bootstrap.css", "public/css/font-awesome.css", "public/css/octicons/octicons.css", - "public/css/c3.min.css", "public/css/desk.css", "public/css/indicator.css", "public/css/avatar.css", @@ -114,7 +113,7 @@ "public/css/form.css", "public/css/mobile.css", "public/css/kanban.css", - "public/css/graphs.css" + "public/css/charts.css" ], "css/frappe-rtl.css": [ "public/css/bootstrap-rtl.css", @@ -231,16 +230,11 @@ "public/js/frappe/query_string.js", "public/js/frappe/ui/charts.js", - "public/js/frappe/ui/graphs.js", "public/js/frappe/ui/comment.js", "public/js/frappe/misc/rating_icons.html", "public/js/frappe/feedback.js" ], - "js/d3.min.js": [ - "public/js/lib/d3.min.js", - "public/js/lib/c3.min.js" - ], "css/module.min.css": [ "public/css/module.css" ], diff --git a/frappe/public/css/c3.min.css b/frappe/public/css/c3.min.css deleted file mode 100644 index 1e20d5b116..0000000000 --- a/frappe/public/css/c3.min.css +++ /dev/null @@ -1 +0,0 @@ -.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000} \ No newline at end of file diff --git a/frappe/public/css/graphs.css b/frappe/public/css/charts.css similarity index 77% rename from frappe/public/css/graphs.css rename to frappe/public/css/charts.css index e0f62b3cd9..f5d279568a 100644 --- a/frappe/public/css/graphs.css +++ b/frappe/public/css/charts.css @@ -1,74 +1,74 @@ -/* graphs */ -.graph-container .graph-focus-margin { +/* charts */ +.chart-container .graph-focus-margin { margin: 0px 5%; } -.graph-container .graphics { +.chart-container .graphics { margin-top: 10px; padding-top: 10px; padding-bottom: 10px; position: relative; } -.graph-container .graph-stats-group { +.chart-container .graph-stats-group { display: flex; justify-content: space-around; flex: 1; } -.graph-container .graph-stats-container { +.chart-container .graph-stats-container { display: flex; justify-content: space-around; padding-top: 10px; } -.graph-container .graph-stats-container .stats { +.chart-container .graph-stats-container .stats { padding-bottom: 15px; } -.graph-container .graph-stats-container .stats-title { +.chart-container .graph-stats-container .stats-title { color: #8D99A6; } -.graph-container .graph-stats-container .stats-value { +.chart-container .graph-stats-container .stats-value { font-size: 20px; font-weight: 300; } -.graph-container .graph-stats-container .stats-description { +.chart-container .graph-stats-container .stats-description { font-size: 12px; color: #8D99A6; } -.graph-container .graph-stats-container .graph-data .stats-value { +.chart-container .graph-stats-container .graph-data .stats-value { color: #98d85b; } -.graph-container .axis, -.graph-container .chart-label { +.chart-container .axis, +.chart-container .chart-label { font-size: 10px; - fill: #959ba1; + fill: #555b51; } -.graph-container .axis line, -.graph-container .chart-label line { - stroke: rgba(27, 31, 35, 0.1); +.chart-container .axis line, +.chart-container .chart-label line { + stroke: rgba(27, 31, 35, 0.2); } -.graph-container .percentage-graph .progress { +.chart-container .percentage-graph .progress { margin-bottom: 0px; } -.graph-container .data-points circle { +.chart-container .data-points circle { stroke: #fff; stroke-width: 2; } -.graph-container .data-points path { +.chart-container .data-points path { fill: none; stroke-opacity: 1; stroke-width: 2px; } -.graph-container line.dashed { +.chart-container line.dashed { stroke-dasharray: 5,3; } -.graph-container .tick.x-axis-label { +.chart-container .tick.x-axis-label { display: block; } -.graph-container .tick .specific-value { +.chart-container .tick .specific-value { text-anchor: start; } -.graph-container .tick .y-value-text { +.chart-container .tick .y-value-text { text-anchor: end; } -.graph-container .tick .x-value-text { +.chart-container .tick .x-value-text { text-anchor: middle; } .graph-svg-tip { @@ -138,6 +138,9 @@ .stroke.light-green { stroke: #98d85b; } +.stroke.lightgreen { + stroke: #98d85b; +} .stroke.green { stroke: #28a745; } @@ -174,6 +177,9 @@ .fill.light-green { fill: #98d85b; } +.fill.lightgreen { + fill: #98d85b; +} .fill.green { fill: #28a745; } @@ -210,6 +216,9 @@ .background.light-green { background: #98d85b; } +.background.lightgreen { + background: #98d85b; +} .background.green { background: #28a745; } @@ -246,6 +255,9 @@ .border-top.light-green { border-top: 3px solid #98d85b; } +.border-top.lightgreen { + border-top: 3px solid #98d85b; +} .border-top.green { border-top: 3px solid #28a745; } diff --git a/frappe/public/js/frappe/form/dashboard.js b/frappe/public/js/frappe/form/dashboard.js index ec96d2a51a..9c84a07af0 100644 --- a/frappe/public/js/frappe/form/dashboard.js +++ b/frappe/public/js/frappe/form/dashboard.js @@ -11,7 +11,7 @@ frappe.ui.form.Dashboard = Class.extend({ this.progress_area = this.wrapper.find(".progress-area"); this.heatmap_area = this.wrapper.find('.form-heatmap'); - this.graph_area = this.wrapper.find('.form-graph'); + this.chart_area = this.wrapper.find('.form-graph'); this.stats_area = this.wrapper.find('.form-stats'); this.stats_area_row = this.stats_area.find('.row'); this.links_area = this.wrapper.find('.form-links'); @@ -334,11 +334,12 @@ frappe.ui.form.Dashboard = Class.extend({ // heatmap render_heatmap: function() { if(!this.heatmap) { - this.heatmap = new frappe.ui.HeatMap({ - parent: this.heatmap_area.find("#heatmap-" + frappe.model.scrub(this.frm.doctype)), + this.heatmap = new frappe.chart.FrappeChart({ + parent: "#heatmap-" + frappe.model.scrub(this.frm.doctype), + type: 'heatmap', height: 100, start: new Date(moment().subtract(1, 'year').toDate()), - count_label: "items", + count_label: frappe.model.scrub(this.frm.doctype) + "s", discrete_domains: 0 }); @@ -403,16 +404,25 @@ frappe.ui.form.Dashboard = Class.extend({ render_graph: function(args) { var me = this; - this.graph_area.empty().removeClass('hidden'); + this.chart_area.empty().removeClass('hidden'); $.extend(args, { - parent: me.graph_area, - mode: 'line', + parent: '.form-graph', + type: 'line', height: 140 }); - new frappe.ui.Graph(args); + this.show(); + + this.chart = new frappe.chart.FrappeChart(args); + if(!this.chart) { + this.hide(); + } }, show: function() { this.section.removeClass('hidden'); + }, + + hide: function() { + this.section.addClass('hidden'); } }); diff --git a/frappe/public/js/frappe/ui/charts.js b/frappe/public/js/frappe/ui/charts.js index 054f1bdc36..8927f2e21b 100644 --- a/frappe/public/js/frappe/ui/charts.js +++ b/frappe/public/js/frappe/ui/charts.js @@ -1,109 +1,1556 @@ -frappe.provide("frappe.ui"); +// specific_values = [ +// { +// title: "Average", +// line_type: "dashed", // "dashed" or "solid" +// value: 10 +// }, -frappe.ui.Chart = Class.extend({ - init: function(opts) { - this.opts = {}; - $.extend(this.opts, opts); - this.show_chart(false); +// summary = [ +// { +// title: "Total", +// color: 'blue', // Indicator colors: 'grey', 'blue', 'red', 'green', 'orange', +// // 'purple', 'darkgrey', 'black', 'yellow', 'lightblue' +// value: 80 +// } +// ] - $(this.opts.wrapper).html('' + - '
=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(oa.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},oa.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),oa.behavior={},oa.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},oa.event=null,oa.requote=function(n){return n.replace(wa,"\\$&")};var wa=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,Sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ka=function(n,t){return t.querySelector(n)},Na=function(n,t){return t.querySelectorAll(n)},Ea=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ea=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(ka=function(n,t){return Sizzle(n,t)[0]||null},Na=Sizzle,Ea=Sizzle.matchesSelector),oa.selection=function(){return oa.select(sa.documentElement)};var Aa=oa.selection.prototype=[];Aa.select=function(n){var t,e,r,u,i=[];n=A(n);for(var a=-1,o=this.length;++a =0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||pl,r=dl.get(r)||y,br(r(e.apply(null,la.call(arguments,1))))},oa.interpolateHcl=Rr,oa.interpolateHsl=Dr,oa.interpolateLab=Pr,oa.interpolateRound=Ur,oa.transform=function(n){var t=sa.createElementNS(oa.ns.prefix.svg,"g");return(oa.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:ml)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ml={a:1,b:0,c:0,d:1,e:0,f:0};oa.interpolateTransform=$r,oa.layout={},oa.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++et;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;u>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",f)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(i=[],"function"==typeof h)for(t=0;c>t;++t)i[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)i[t]=h;if(a=[],"function"==typeof g)for(t=0;c>t;++t)a[t]=+g.call(this,x[t],t);else for(t=0;c>t;++t)a[t]=g;if(o=[],"function"==typeof p)for(t=0;u>t;++t)o[t]=+p.call(this,M[t],t);else for(t=0;u>t;++t)o[t]=p;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=oa.behavior.drag().origin(y).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",nu)),arguments.length?void this.on("mouseover.force",tu).on("mouseout.force",eu).call(r):r},oa.rebind(l,c,"on")};var yl=20,Ml=1,xl=1/0;oa.layout.hierarchy=function(){function n(u){var i,a=[u],o=[];for(u.depth=0;null!=(i=a.pop());)if(o.push(i),(c=e.call(n,i,i.depth))&&(l=c.length)){for(var l,c,s;--l>=0;)a.push(s=c[l]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=c}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return au(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),o}var t=cu,e=ou,r=lu;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(iu(t,function(n){n.children&&(n.value=0)}),au(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},oa.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(a=i.length)){var a,o,l,c=-1;for(r=t.value?r/t.value:0;++cf?-1:1),p=oa.sum(c),v=p?(f-l*g)/p:0,d=oa.range(l),m=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(a[n],a[t])}),d.forEach(function(n){m[n]={data:a[n],value:o=c[n],startAngle:s,endAngle:s+=o*v+g,padAngle:h}}),m}var t=Number,e=bl,r=0,u=Fa,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var bl={};oa.layout.stack=function(){function n(o,l){if(!(h=o.length))return o;var c=o.map(function(e,r){return t.call(n,e,r)}),s=c.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),a.call(n,t,e)]})}),f=e.call(n,s,l);c=oa.permute(c,f),s=oa.permute(s,f);var h,g,p,v,d=r.call(n,s,l),m=c[0].length;for(p=0;m>p;++p)for(u.call(n,c[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,c[g][p],v+=s[g-1][p][1],s[g][p][1]);return o}var t=y,e=pu,r=vu,u=gu,i=fu,a=hu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||pu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vu,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(a=t,n):a},n.out=function(t){return arguments.length?(u=t,n):u},n};var _l=oa.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(du),i=n.map(mu),a=oa.range(r).sort(function(n,t){return u[n]-u[t]}),o=0,l=0,c=[],s=[];for(t=0;r>t;++t)e=a[t],l>o?(o+=i[e],c.push(e)):(l+=i[e],s.push(e));return s.reverse().concat(c)},reverse:function(n){return oa.range(n.length).reverse()},"default":pu}),wl=oa.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,a=[],o=0,l=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>o&&(o=r),a.push(r)}for(e=0;i>e;++e)l[e]=(o-a[e])/2;return l},wiggle:function(n){var t,e,r,u,i,a,o,l,c,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=l=c=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,o=f[e][0]-f[e-1][0];s>t;++t){for(r=0,a=(n[t][e][1]-n[t][e-1][1])/(2*o);t>r;++r)a+=(n[r][e][1]-n[r][e-1][1])/o;i+=a*n[t][e][1]}g[e]=l-=u?i/u*o:0,c>l&&(c=l)}for(e=0;h>e;++e)g[e]-=c;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,a=1/u,o=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=a}for(e=0;i>e;++e)o[e]=0;return o},zero:vu});oa.layout.histogram=function(){function n(n,i){for(var a,o,l=[],c=n.map(e,this),s=r.call(this,c,i),f=u.call(this,s,c,i),i=-1,h=c.length,g=f.length-1,p=t?1:1/h;++i