Merge authors: Jan Henrik Øverland (janhenrik-overland) ------------------------------------------------------------ revno: 18747 [merge] committer: Jan Henrik Overland <janhenrik.overl...@gmail.com> branch nick: dhis2 timestamp: Mon 2015-03-30 15:38:30 +0200 message: DV code sync. modified: dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/chart.js dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/chart.js dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/chart.js dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js
-- lp:dhis2 https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk Your team DHIS 2 developers is subscribed to branch lp:dhis2. To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js 2015-03-28 16:52:19 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js 2015-03-30 13:36:53 +0000 @@ -237,7 +237,7 @@ markerConfig, label, mask, radius, toggle = false, seriesStyle = Ext.apply(series.seriesStyle, series.style), - labelMarkerSize = legend.labelMarkerSize || 12; + labelMarkerSize = legend.labelMarkerSize || 10; function getSeriesProp(name) { var val = series[name]; @@ -246,7 +246,7 @@ label = me.add('label', surface.add({ type: 'text', - x: 0, + x: 30, y: 0, zIndex: z || 0, font: legend.labelFont, @@ -3639,10 +3639,10 @@ shadow: false, insetPadding: ns.dashboard ? 17 : 35, insetPaddingObject: { - top: 10, - right: isLineBased ? 5 : 3, - bottom: 2, - left: isLineBased ? 15 : 7 + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : 10, + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : 17 }, width: ns.dashboard ? width : width - 15, height: ns.dashboard ? height : height - 40, === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/chart.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/chart.js 2015-03-28 16:52:19 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/chart.js 2015-03-30 13:36:53 +0000 @@ -237,7 +237,7 @@ markerConfig, label, mask, radius, toggle = false, seriesStyle = Ext.apply(series.seriesStyle, series.style), - labelMarkerSize = legend.labelMarkerSize || 12; + labelMarkerSize = legend.labelMarkerSize || 10; function getSeriesProp(name) { var val = series[name]; @@ -246,7 +246,7 @@ label = me.add('label', surface.add({ type: 'text', - x: 0, + x: 30, y: 0, zIndex: z || 0, font: legend.labelFont, @@ -351,8 +351,7 @@ label.setAttributes({ opacity: 0.5 }, true); - } - else { + } else { series.showAll(); label.setAttributes({ opacity: 1 @@ -3195,16 +3194,17 @@ store = config.store || {}, width = ns.app.centerRegion.getWidth(), height = ns.app.centerRegion.getHeight(), + isLineBased = Ext.Array.contains(['line', 'area'], xLayout.type), defaultConfig = { //animate: true, animate: false, shadow: false, insetPadding: ns.dashboard ? 17 : 35, insetPaddingObject: { - top: 10, - right: 3, - bottom: 2, - left: 7 + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : 10, + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : 17 }, width: ns.dashboard ? width : width - 15, height: ns.dashboard ? height : height - 40, === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js 2015-02-25 14:51:26 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js 2015-03-30 13:36:53 +0000 @@ -3,27 +3,519 @@ // ext config Ext.Ajax.method = 'GET'; + Ext.isIE = (/trident/.test(Ext.userAgent)); + + Ext.isIE11 = Ext.isIE && (/rv:11.0/.test(Ext.userAgent)); + + Ext.util.CSS.createStyleSheet = function(cssText, id) { + var ss, + head = document.getElementsByTagName("head")[0], + styleEl = document.createElement("style"); + + styleEl.setAttribute("type", "text/css"); + + if (id) { + styleEl.setAttribute("id", id); + } + + if (Ext.isIE && !Ext.isIE11) { + head.appendChild(styleEl); + ss = styleEl.styleSheet; + ss.cssText = cssText; + } + else { + try { + styleEl.appendChild(document.createTextNode(cssText)); + } + catch(e) { + styleEl.cssText = cssText; + } + head.appendChild(styleEl); + ss = styleEl.styleSheet ? styleEl.styleSheet : (styleEl.sheet || document.styleSheets[document.styleSheets.length-1]); + } + this.cacheStyleSheet(ss); + return ss; + }; + // override + Ext.override(Ext.chart.Chart, { + insetPaddingObject: {}, + + alignAxes: function() { + var me = this, + axes = me.axes, + legend = me.legend, + edges = ['top', 'right', 'bottom', 'left'], + chartBBox, + insetPadding = me.insetPadding, + insetPaddingObject = me.insetPaddingObject, + insets = { + top: insetPaddingObject.top || insetPadding, + right: insetPaddingObject.right || insetPadding, + bottom: insetPaddingObject.bottom || insetPadding, + left: insetPaddingObject.left || insetPadding + }; + + function getAxis(edge) { + var i = axes.findIndex('position', edge); + return (i < 0) ? null : axes.getAt(i); + } + + + Ext.each(edges, function(edge) { + var isVertical = (edge === 'left' || edge === 'right'), + axis = getAxis(edge), + bbox; + + + if (legend !== false) { + if (legend.position === edge) { + bbox = legend.getBBox(); + insets[edge] += (isVertical ? bbox.width : bbox.height) + insets[edge]; + } + } + + + + if (axis && axis.bbox) { + bbox = axis.bbox; + insets[edge] += (isVertical ? bbox.width : bbox.height); + } + }); + + chartBBox = { + x: insets.left, + y: insets.top, + width: me.curWidth - insets.left - insets.right, + height: me.curHeight - insets.top - insets.bottom + }; + me.chartBBox = chartBBox; + + + + axes.each(function(axis) { + var pos = axis.position, + isVertical = (pos === 'left' || pos === 'right'); + + axis.x = (pos === 'right' ? chartBBox.x + chartBBox.width : chartBBox.x); + axis.y = (pos === 'top' ? chartBBox.y : chartBBox.y + chartBBox.height); + axis.width = (isVertical ? chartBBox.width : chartBBox.height); + axis.length = (isVertical ? chartBBox.height : chartBBox.width); + }); + } + }); + Ext.override(Ext.chart.series.Line, { drawSeries: function() { var ak=this,au=ak.chart,S=au.axes,ao=au.getChartStore(),V=ao.getCount(),u=ak.chart.surface,am={},R=ak.group,K=ak.showMarkers,aA=ak.markerGroup,D=au.shadow,C=ak.shadowGroups,X=ak.shadowAttributes,O=ak.smooth,q=C.length,ar=["M"],T=["M"],d=["M"],b=["M"],J=au.markerIndex,ai=[].concat(ak.axis),ah,av=[],ag={},aa=[],v={},I=false,Q=[],az=ak.markerStyle,Z=ak.style,t=ak.colorArrayStyle,P=t&&t.length||0,L=Ext.isNumber,aw=ak.seriesIdx,g=ak.getAxesForXAndYFields(),l=g.xAxis,ay=g.yAxis,ac,h,ab,ad,A,c,ae,H,G,f,e,s,r,W,N,M,at,m,F,E,aB,n,p,B,a,Y,af,z,aq,w,ap,o,ax,an,al,U,k,aj;if(ak.fireEvent("beforedraw",ak)===false){return}if(!V||ak.seriesIsHidden){aj=this.items;if(aj){for(N=0,at=aj.length;N<at;++N){if(aj[N].sprite){aj[N].sprite.hide(true)}}}return}an=Ext.apply(az||{},ak.markerConfig);U=an.type;delete an.type;al=Z;if(!al["stroke-width"]){al["stroke-width"]=0.5}if(J&&aA&&aA.getCount()){for(N=0;N<J;N++){E=aA.getAt(N);aA.remove(E);aA.add(E);aB=aA.getAt(aA.getCount()-2);E.setAttributes({x:0,y:0,translate:{x:aB.attr.translation.x,y:aB.attr.translation.y}},true)}}ak.unHighlightItem();ak.cleanHighlights();ak.setBBox();am=ak.bbox;ak.clipRect=[am.x,am.y,am.width,am.height];for(N=0,at=ai.length;N<at;N++){m=S.get(ai[N]);if(m){F=m.calcEnds();if(m.position=="top"||m.position=="bottom"){z=F.from;aq=F.to}else{w=F.from;ap=F.to}}}if(ak.xField&&!L(z)&&(l=="bottom"||l=="top")&&!S.get(l)){m=Ext.create("Ext.chart.axis.Axis",{chart:au,fields:[].concat(ak.xField)}).calcEnds();z=m.from;aq=m.to}if(ak.yField&&!L(w)&&(ay=="right"||ay=="left")&&!S.get(ay)){m=Ext.create("Ext.chart.axis.Axis",{chart:au,fields:[].concat(ak.yField)}).calcEnds();w=m.from;ap=m.to}if(isNaN(z)){z=0;Y=am.width/((V-1)||1)}else{Y=am.width/((aq-z)||(V-1)||1)}if(isNaN(w)){w=0;af=am.height/((V-1)||1)}else{af=am.height/((ap-w)||(V-1)||1)}ak.eachRecord(function(j,x){p=j.get(ak.xField);if(typeof p=="string"||typeof p=="object"&&!Ext.isDate(p)||l&&S.get(l)&&S.get(l).type=="Category"){if(p in ag){p=ag[p]}else{p=ag[p]=x}}B=j.get(ak.yField);if(typeof B=="undefined"||(typeof B=="string"&&!B)){if(Ext.isDefined(Ext.global.console)){Ext.global.console.warn("[Ext.chart.series.Line] Skipping a store element with an undefined value at ",j,p,B)}return}if(typeof B=="object"&&!Ext.isDate(B)||ay&&S.get(ay)&&S.get(ay).type=="Category"){B=x}Q.push(x);av.push(p);aa.push(B)});at=av.length;if(at>am.width){a=ak.shrink(av,aa,am.width);av=a.x;aa=a.y}ak.items=[];k=0;at=av.length;for(N=0;N<at;N++){p=av[N];B=aa[N];if(B===false){if(T.length==1){T=[]}I=true;ak.items.push(false);continue}else{H=(am.x+(p-z)*Y).toFixed(2);G=((am.y+am.height)-(B-w)*af).toFixed(2);if(I){I=false;T.push("M")}T=T.concat([H,G])}if((typeof r=="undefined")&&(typeof G!="undefined")){r=G;s=H}if(!ak.line||au.resizing){ar=ar.concat([H,am.y+am.height/2])}if(au.animate&&au.resizing&&ak.line){ak.line.setAttributes({path:ar},true);if(ak.fillPath){ak.fillPath.setAttributes({path:ar,opacity:0.2},true)}if(ak.line.shadows){ac=ak.line.shadows;for(M=0,q=ac.length;M<q;M++){h=ac[M];h.setAttributes({path:ar},true)}}}if(K){E=aA.getAt(k++);if(!E){E=Ext.chart.Shape[U](u,Ext.apply({group:[R,aA],x:0,y:0,translate:{x:+(f||H),y:e||(am.y+am.height/2)},value:'"'+p+", "+B+'"',zIndex:4000},an));E._to={translate:{x:+H,y:+G}}}else{E.setAttributes({value:'"'+p+", "+B+'"',x:0,y:0,hidden:false},true);E._to={translate:{x:+H,y:+G}}}}ak.items.push({series:ak,value:[p,B],point:[H,G],sprite:E,storeItem:ao.getAt(Q[N])});f=H;e=G}if(T.length<=1){return}if(ak.smooth){b=Ext.draw.Draw.smooth(T,L(O)?O:ak.defaultSmoothness)}d=O?b:T;if(au.markerIndex&&ak.previousPath){ad=ak.previousPath;if(!O){Ext.Array.erase(ad,1,2)}}else{ad=T}if(!ak.line){ak.line=u.add(Ext.apply({type:"path",group:R,path:ar,stroke:al.stroke||al.fill},al||{}));if(D){ak.line.setAttributes(Ext.apply({},ak.shadowOptions),true)}ak.line.setAttributes({fill:"none",zIndex:3000});if(!al.stroke&&P){ak.line.setAttributes({stroke:t[aw%P]},true)}if(D){ac=ak.line.shadows=[];for(ab=0;ab<q;ab++){ah=X[ab];ah=Ext.apply({},ah,{path:ar});h=u.add(Ext.apply({},{type:"path",group:C[ab]},ah));ac.push(h)}}}if(ak.fill){c=d.concat([["L",H,am.y+am.height],["L",s,am.y+am.height],["L",s,r]]);if(!ak.fillPath){ak.fillPath=u.add({group:R,type:"path",opacity:al.opacity||0.3,fill:al.fill||t[aw%P],path:ar})}}W=K&&aA.getCount();if(au.animate){A=ak.fill;o=ak.line;ae=ak.renderer(o,false,{path:d},N,ao);Ext.apply(ae,al||{},{stroke:al.stroke||al.fill});delete ae.fill;o.show(true);if(au.markerIndex&&ak.previousPath){ak.animation=ax=ak.onAnimate(o,{to:ae,from:{path:ad}})}else{ak.animation=ax=ak.onAnimate(o,{to:ae})}if(D){ac=o.shadows;for(M=0;M<q;M++){ac[M].show(true);if(au.markerIndex&&ak.previousPath){ak.onAnimate(ac[M],{to:{path:d},from:{path:ad}})}else{ak.onAnimate(ac[M],{to:{path:d}})}}}if(A){ak.fillPath.show(true);ak.onAnimate(ak.fillPath,{to:Ext.apply({},{path:c,fill:al.fill||t[aw%P],"stroke-width":0},al||{})})}if(K){k=0;for(N=0;N<at;N++){if(ak.items[N]){n=aA.getAt(k++);if(n){ae=ak.renderer(n,ao.getAt(N),n._to,N,ao);ak.onAnimate(n,{to:Ext.apply(ae,an||{})});n.show(true)}}}for(;k<W;k++){n=aA.getAt(k);n.hide(true)}}}else{ae=ak.renderer(ak.line,false,{path:d,hidden:false},N,ao);Ext.apply(ae,al||{},{stroke:al.stroke||al.fill});delete ae.fill;ak.line.setAttributes(ae,true);if(D){ac=ak.line.shadows;for(M=0;M<q;M++){ac[M].setAttributes({path:d,hidden:false},true)}}if(ak.fill){ak.fillPath.setAttributes({path:c,hidden:false},true)}if(K){k=0;for(N=0;N<at;N++){if(ak.items[N]){n=aA.getAt(k++);if(n){ae=ak.renderer(n,ao.getAt(N),n._to,N,ao);n.setAttributes(Ext.apply(an||{},ae||{}),true);n.show(true)}}}for(;k<W;k++){n=aA.getAt(k);n.hide(true)}}}if(au.markerIndex){if(ak.smooth){Ext.Array.erase(T,1,2)}else{Ext.Array.splice(T,1,0,T[1],T[2])}ak.previousPath=T}ak.renderLabels();ak.renderCallouts();ak.fireEvent("draw",ak); } }); - Ext.isIE = function() { - return /trident/.test(Ext.userAgent); - }(); + Ext.override(Ext.chart.Legend, { + updatePosition: function() { + var me = this, + x, y, + legendWidth = me.width, + legendHeight = me.height, + padding = me.padding, + chart = me.chart, + chartBBox = chart.chartBBox, + insets = chart.insetPadding, + chartWidth = chartBBox.width - (insets * 2), + chartHeight = chartBBox.height - (insets * 2), + chartX = chartBBox.x + insets, + chartY = chartBBox.y + insets, + surface = chart.surface, + mfloor = Math.floor; + + if (me.isDisplayed()) { + // Find the position based on the dimensions + switch(me.position) { + case "left": + x = insets; + y = mfloor(chartY + chartHeight / 2 - legendHeight / 2); + break; + case "right": + x = mfloor(surface.width - legendWidth) - insets; + y = mfloor(chartY + chartHeight / 2 - legendHeight / 2); + break; + case "top": + x = mfloor((chartX + chartBBox.width) / 2 - legendWidth / 2) - 7; + y = insets; + break; + case "bottom": + x = mfloor(chartX + chartWidth / 2 - legendWidth / 2); + y = mfloor(surface.height - legendHeight) - insets; + break; + default: + x = mfloor(me.origX) + insets; + y = mfloor(me.origY) + insets; + } + me.x = x; + me.y = y; + + // Update the position of each item + Ext.each(me.items, function(item) { + item.updatePosition(); + }); + // Update the position of the outer box + me.boxSprite.setAttributes(me.getBBox(), true); + } + } + }); + + Ext.override(Ext.chart.LegendItem, { + createLegend: function(config) { + var me = this, + index = config.yFieldIndex, + series = me.series, + seriesType = series.type, + idx = me.yFieldIndex, + legend = me.legend, + surface = me.surface, + refX = legend.x + me.x, + refY = legend.y + me.y, + bbox, z = me.zIndex, + markerConfig, label, mask, + radius, toggle = false, + seriesStyle = Ext.apply(series.seriesStyle, series.style), + labelMarkerSize = legend.labelMarkerSize || 10; + + function getSeriesProp(name) { + var val = series[name]; + return (Ext.isArray(val) ? val[idx] : val); + } + + label = me.add('label', surface.add({ + type: 'text', + x: 30, + y: 0, + zIndex: z || 0, + font: legend.labelFont, + fill: legend.labelColor || '#000', + text: getSeriesProp('title') || getSeriesProp('yField') + })); + + if (seriesType === 'line' || seriesType === 'scatter') { + if (seriesType === 'line') { + me.add('line', surface.add({ + type: 'path', + path: 'M0.5,0.5L16.5,0.5', + zIndex: z, + "stroke-width": series.lineWidth, + "stroke-linejoin": "round", + "stroke-dasharray": series.dash, + stroke: seriesStyle.stroke || '#000', + style: { + cursor: 'pointer' + } + })); + } + if (series.showMarkers || seriesType === 'scatter') { + markerConfig = Ext.apply(series.markerStyle, series.markerConfig || {}); + me.add('marker', Ext.chart.Shape[markerConfig.type](surface, { + fill: markerConfig.fill, + x: 8.5, + y: 0.5, + zIndex: z, + radius: markerConfig.radius || markerConfig.size, + style: { + cursor: 'pointer' + } + })); + } + } + else { + me.add('box', surface.add({ + type: 'rect', + zIndex: z, + x: 6, + y: 0, + width: labelMarkerSize, + height: labelMarkerSize, + fill: series.getLegendColor(index), + style: { + cursor: 'pointer' + } + })); + } + + me.setAttributes({ + hidden: false + }, true); + + bbox = me.getBBox(); + + mask = me.add('mask', surface.add({ + type: 'rect', + x: bbox.x, + y: bbox.y, + width: bbox.width || 20, + height: bbox.height || 20, + zIndex: (z || 0) + 1000, + fill: '#f00', + opacity: 0, + style: { + 'cursor': 'pointer' + } + })); + + + me.on('mouseover', function() { + label.setStyle({ + 'font-weight': 'bold' + }); + mask.setStyle({ + 'cursor': 'pointer' + }); + series._index = index; + series.highlightItem(); + }, me); + + me.on('mouseout', function() { + label.setStyle({ + 'font-weight': 'normal' + }); + series._index = index; + series.unHighlightItem(); + }, me); + + if (!series.visibleInLegend(index)) { + toggle = true; + label.setAttributes({ + opacity: 0.5 + }, true); + } + + me.on('mousedown', function() { + if (!toggle) { + series.hideAll(); + label.setAttributes({ + opacity: 0.5 + }, true); + } else { + series.showAll(); + label.setAttributes({ + opacity: 1 + }, true); + } + toggle = !toggle; + }, me); + me.updatePosition({x:0, y:0}); + } + }); + + Ext.override(Ext.chart.axis.Axis, { + drawHorizontalLabels: function() { + var me = this, + labelConf = me.label, + floor = Math.floor, + max = Math.max, + axes = me.chart.axes, + position = me.position, + inflections = me.inflections, + ln = inflections.length, + labels = me.labels, + labelGroup = me.labelGroup, + maxHeight = 0, + ratio, + gutterY = me.chart.maxGutter[1], + ubbox, bbox, point, prevX, prevLabel, + projectedWidth = 0, + textLabel, attr, textRight, text, + label, last, x, y, i, firstLabel; + + last = ln - 1; + // get a reference to the first text label dimensions + point = inflections[0]; + firstLabel = me.getOrCreateLabel(0, me.label.renderer(labels[0])); + ratio = Math.floor(Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0))); + + for (i = 0; i < ln; i++) { + point = inflections[i]; + text = me.label.renderer(labels[i]) || ''; + textLabel = me.getOrCreateLabel(i, text); + bbox = textLabel._bbox; + maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding); + x = floor(point[0] - (ratio? bbox.height : bbox.width) / 2); + if (me.chart.maxGutter[0] == 0) { + if (i == 0 && axes.findIndex('position', 'left') == -1) { + x = point[0]; + } + else if (i == last && axes.findIndex('position', 'right') == -1) { + x = point[0] - bbox.width; + } + } + if (position == 'top') { + y = point[1] - (me.dashSize * 2) - me.label.padding - (bbox.height / 2); + } + else { + y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2); + } + + var moveLabels = labelConf.rotate && labelConf.rotate.degrees && !Ext.Array.contains([0,90,180,270,360], labelConf.rotate.degrees), + adjust = Math.floor((textLabel.text.length - 12) * -1 * 0.75), + newX = moveLabels ? point[0] - textLabel._bbox.width + adjust: x; + + textLabel.setAttributes({ + hidden: false, + x: newX, + y: y + }, true); + + // skip label if there isn't available minimum space + if (i != 0 && (me.intersect(textLabel, prevLabel) + || me.intersect(textLabel, firstLabel))) { + textLabel.hide(true); + continue; + } + + prevLabel = textLabel; + } + + return maxHeight; + } + }); + + Ext.override(Ext.chart.axis.Radial, { + drawLabel: function() { + var chart = this.chart, + surface = chart.surface, + bbox = chart.chartBBox, + store = chart.store, + centerX = bbox.x + (bbox.width / 2), + centerY = bbox.y + (bbox.height / 2), + rho = Math.min(bbox.width, bbox.height) /2, + max = Math.max, round = Math.round, + labelArray = [], label, + fields = [], nfields, + categories = [], xField, + aggregate = !this.maximum, + maxValue = this.maximum || 0, + steps = this.steps, i = 0, j, dx, dy, + pi2 = Math.PI * 2, + cos = Math.cos, sin = Math.sin, + display = this.label.display, + draw = display !== 'none', + margin = 10, + + labelColor = '#333', + labelFont = 'normal 9px sans-serif', + seriesStyle = chart.seriesStyle; + + labelColor = seriesStyle ? seriesStyle.labelColor : labelColor; + labelFont = seriesStyle ? seriesStyle.labelFont : labelFont; + + if (!draw) { + return; + } + + //get all rendered fields + chart.series.each(function(series) { + fields.push(series.yField); + xField = series.xField; + }); + + //get maxValue to interpolate + store.each(function(record, i) { + if (aggregate) { + for (i = 0, nfields = fields.length; i < nfields; i++) { + maxValue = max(+record.get(fields[i]), maxValue); + } + } + categories.push(record.get(xField)); + }); + if (!this.labelArray) { + if (display != 'categories') { + //draw scale + for (i = 1; i <= steps; i++) { + label = surface.add({ + type: 'text', + text: round(i / steps * maxValue), + x: centerX, + y: centerY - rho * i / steps, + 'text-anchor': 'middle', + 'stroke-width': 0.1, + stroke: '#333', + fill: labelColor, + font: labelFont + }); + label.setAttributes({ + hidden: false + }, true); + labelArray.push(label); + } + } + if (display != 'scale') { + //draw text + for (j = 0, steps = categories.length; j < steps; j++) { + dx = cos(j / steps * pi2) * (rho + margin); + dy = sin(j / steps * pi2) * (rho + margin); + label = surface.add({ + type: 'text', + text: categories[j], + x: centerX + dx, + y: centerY + dy, + 'text-anchor': dx * dx <= 0.001? 'middle' : (dx < 0? 'end' : 'start'), + fill: labelColor, + font: labelFont + }); + label.setAttributes({ + hidden: false + }, true); + labelArray.push(label); + } + } + } + else { + labelArray = this.labelArray; + if (display != 'categories') { + //draw values + for (i = 0; i < steps; i++) { + labelArray[i].setAttributes({ + text: round((i + 1) / steps * maxValue), + x: centerX, + y: centerY - rho * (i + 1) / steps, + 'text-anchor': 'middle', + 'stroke-width': 0.1, + stroke: '#333', + fill: labelColor, + font: labelFont + }, true); + } + } + if (display != 'scale') { + //draw text + for (j = 0, steps = categories.length; j < steps; j++) { + dx = cos(j / steps * pi2) * (rho + margin); + dy = sin(j / steps * pi2) * (rho + margin); + if (labelArray[i + j]) { + labelArray[i + j].setAttributes({ + type: 'text', + text: categories[j], + x: centerX + dx, + y: centerY + dy, + 'text-anchor': dx * dx <= 0.001? 'middle' : (dx < 0? 'end' : 'start'), + fill: labelColor, + font: labelFont + }, true); + } + } + } + } + this.labelArray = labelArray; + } + }); // namespace DV = {}; - NS = DV; - - NS.instances = []; - NS.i18n = {}; - NS.isDebug = false; - NS.isSessionStorage = ('sessionStorage' in window && window['sessionStorage'] !== null); - - NS.getCore = function(init) { + + DV.instances = []; + DV.i18n = {}; + DV.isDebug = false; + DV.isSessionStorage = ('sessionStorage' in window && window['sessionStorage'] !== null); + + DV.getCore = function(init) { var conf = {}, api = {}, support = {}, @@ -50,19 +542,19 @@ dimension: { data: { value: 'data', - name: NS.i18n.data, + name: DV.i18n.data, dimensionName: 'dx', objectName: 'dx' }, indicator: { value: 'indicator', - name: NS.i18n.indicator, + name: DV.i18n.indicator, dimensionName: 'dx', objectName: 'in' }, dataElement: { value: 'dataelement', - name: NS.i18n.data_element, + name: DV.i18n.data_element, dimensionName: 'dx', objectName: 'de' }, @@ -74,18 +566,18 @@ }, dataSet: { value: 'dataset', - name: NS.i18n.dataset, + name: DV.i18n.dataset, dimensionName: 'dx', objectName: 'ds' }, category: { - name: NS.i18n.assigned_categories, + name: DV.i18n.assigned_categories, dimensionName: 'co', objectName: 'co', }, period: { value: 'period', - name: NS.i18n.period, + name: DV.i18n.period, dimensionName: 'pe', objectName: 'pe', }, @@ -97,7 +589,7 @@ }, organisationUnit: { value: 'organisationUnits', - name: NS.i18n.organisation_units, + name: DV.i18n.organisation_units, dimensionName: 'ou', objectName: 'ou', }, @@ -158,17 +650,17 @@ conf.period = { periodTypes: [ - {id: 'Daily', name: NS.i18n.daily}, - {id: 'Weekly', name: NS.i18n.weekly}, - {id: 'Monthly', name: NS.i18n.monthly}, - {id: 'BiMonthly', name: NS.i18n.bimonthly}, - {id: 'Quarterly', name: NS.i18n.quarterly}, - {id: 'SixMonthly', name: NS.i18n.sixmonthly}, - {id: 'SixMonthlyApril', name: NS.i18n.sixmonthly_april}, - {id: 'Yearly', name: NS.i18n.yearly}, - {id: 'FinancialOct', name: NS.i18n.financial_oct}, - {id: 'FinancialJuly', name: NS.i18n.financial_july}, - {id: 'FinancialApril', name: NS.i18n.financial_april} + {id: 'Daily', name: DV.i18n.daily}, + {id: 'Weekly', name: DV.i18n.weekly}, + {id: 'Monthly', name: DV.i18n.monthly}, + {id: 'BiMonthly', name: DV.i18n.bimonthly}, + {id: 'Quarterly', name: DV.i18n.quarterly}, + {id: 'SixMonthly', name: DV.i18n.sixmonthly}, + {id: 'SixMonthlyApril', name: DV.i18n.sixmonthly_april}, + {id: 'Yearly', name: DV.i18n.yearly}, + {id: 'FinancialOct', name: DV.i18n.financial_oct}, + {id: 'FinancialJuly', name: DV.i18n.financial_july}, + {id: 'FinancialApril', name: DV.i18n.financial_april} ] }; @@ -180,7 +672,7 @@ west_fill_accordion_indicator: 56, west_fill_accordion_dataelement: 59, west_fill_accordion_dataset: 31, - west_fill_accordion_period: 275, + west_fill_accordion_period: 284, west_fill_accordion_organisationunit: 58, west_maxheight_accordion_indicator: 350, west_maxheight_accordion_dataelement: 350, @@ -280,12 +772,12 @@ return function() { if (!Ext.isObject(config)) { - console.log('Record: config is not an object: ' + config); + ns.alert('Record: config is not an object: ' + config, true); return; } if (!Ext.isString(config.id)) { - alert('Record: id is not text: ' + config); + ns.alert('Record: id is not text: ' + config, true); return; } @@ -494,19 +986,19 @@ // Indicators as filter if (layout.filters[i].dimension === dimConf.indicator.objectName) { - web.message.alert(DV.i18n.indicators_cannot_be_specified_as_filter || 'Indicators cannot be specified as filter'); + ns.alert(DV.i18n.indicators_cannot_be_specified_as_filter || 'Indicators cannot be specified as filter', true); return; } // Categories as filter if (layout.filters[i].dimension === dimConf.category.objectName) { - web.message.alert(DV.i18n.categories_cannot_be_specified_as_filter || 'Categories cannot be specified as filter'); + ns.alert(DV.i18n.categories_cannot_be_specified_as_filter || 'Categories cannot be specified as filter', true); return; } // Data sets as filter if (layout.filters[i].dimension === dimConf.dataSet.objectName) { - web.message.alert(DV.i18n.data_sets_cannot_be_specified_as_filter || 'Data sets cannot be specified as filter'); + ns.alert(DV.i18n.data_sets_cannot_be_specified_as_filter || 'Data sets cannot be specified as filter', true); return; } } @@ -514,25 +1006,25 @@ // dc and in if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.indicator.objectName]) { - web.message.alert('Indicators and detailed data elements cannot be specified together'); + ns.alert('Indicators and detailed data elements cannot be specified together', true); return; } // dc and de if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.dataElement.objectName]) { - web.message.alert('Detailed data elements and totals cannot be specified together'); + ns.alert('Detailed data elements and totals cannot be specified together', true); return; } // dc and ds if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.dataSet.objectName]) { - web.message.alert('Data sets and detailed data elements cannot be specified together'); + ns.alert('Data sets and detailed data elements cannot be specified together', true); return; } // dc and co if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.category.objectName]) { - web.message.alert('Categories and detailed data elements cannot be specified together'); + ns.alert('Categories and detailed data elements cannot be specified together', true); return; } @@ -545,7 +1037,7 @@ // config must be an object if (!(config && Ext.isObject(config))) { - alert('Layout: config is not an object (' + init.el + ')'); + ns.alert('Layout: config is not an object (' + init.el + ')', true); return; } @@ -555,12 +1047,12 @@ // at least one dimension specified as column and row if (!config.columns) { - alert('No series items selected'); + ns.alert('No series items selected'); return; } if (!config.rows) { - alert('No category items selected'); + ns.alert('No category items selected'); return; } @@ -575,7 +1067,7 @@ // at least one period if (!Ext.Array.contains(objectNames, dimConf.period.objectName)) { - alert('At least one period must be specified as series, category or filter'); + ns.alert('At least one period must be specified as series, category or filter'); return; } @@ -629,15 +1121,15 @@ if (Ext.isObject(config.domainAxisStyle)) { layout.domainAxisStyle = config.domainAxisStyle; } - + if (Ext.isObject(config.rangeAxisStyle)) { layout.rangeAxisStyle = config.rangeAxisStyle; } - + if (Ext.isObject(config.legendStyle)) { layout.legendStyle = config.legendStyle; } - + if (Ext.isObject(config.seriesStyle)) { layout.seriesStyle = config.seriesStyle; } @@ -705,12 +1197,10 @@ console.log('Response: no valid headers'); return; } - + if (!(Ext.isArray(config.rows) && config.rows.length > 0)) { - if (!NS.plugin) { - alert('No values found'); - } - return; + init.alert('No values found'); + return; } if (config.headers.length !== config.rows[0].length) { @@ -743,6 +1233,26 @@ return array.length; }; + support.prototype.array.getMaxLength = function(array, suppressWarning) { + if (!Ext.isArray(array)) { + if (!suppressWarning) { + console.log('support.prototype.array.getLength: not an array'); + } + + return null; + } + + var maxLength = 0; + + for (var i = 0; i < array.length; i++) { + if (Ext.isString(array[i]) && array[i].length > maxLength) { + maxLength = array[i].length; + } + } + + return maxLength; + }; + support.prototype.array.sort = function(array, direction, key) { // accepts [number], [string], [{prop: number}], [{prop: string}] @@ -1188,13 +1698,13 @@ ou = dimConf.organisationUnit.objectName, layout; - // set items from init/metaData/xLayout + // Set items from init/metaData/xLayout for (var i = 0, dim, metaDataDim, items; i < dimensions.length; i++) { dim = dimensions[i]; dim.items = []; metaDataDim = response.metaData[dim.objectName]; - // if ou and children + // If ou and children if (dim.dimensionName === ou) { if (isUserOrgunit || isUserOrgunitChildren || isUserOrgunitGrandChildren) { var userOu, @@ -1279,7 +1789,7 @@ } } - // re-layout + // Re-layout layout = api.layout.Layout(xLayout); if (layout) { @@ -1609,6 +2119,10 @@ web.mask = {}; web.mask.show = function(component, message) { + if (init.skipMask) { + return; + } + if (!Ext.isObject(component)) { console.log('support.gui.mask.show: component not an object'); return null; @@ -1632,6 +2146,10 @@ }; web.mask.hide = function(component) { + if (init.skipMask) { + return; + } + if (!Ext.isObject(component)) { console.log('support.gui.mask.hide: component not an object'); return null; @@ -1643,13 +2161,6 @@ } }; - // message - web.message = {}; - - web.message.alert = function(message) { - console.log(message); - }; - // analytics web.analytics = {}; @@ -1722,7 +2233,7 @@ msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.'; - alert(msg); + ns.alert(msg); }; // chart @@ -1734,7 +2245,7 @@ columnIds = xLayout.columnDimensionNames[0] ? xLayout.dimensionNameIdsMap[xLayout.columnDimensionNames[0]] : [], failSafeColumnIds = [], failSafeColumnIdMap = {}, - createFailSafeIds = function() { + createFailSafeColumnIds = function() { for (var i = 0, uuid; i < columnIds.length; i++) { uuid = Ext.data.IdGenerator.get('uuid').generate(); @@ -1782,7 +2293,9 @@ getDefaultStore, getDefaultNumericAxis, getDefaultCategoryAxis, + getFormatedSeriesTitle, getDefaultSeriesTitle, + getPieSeriesTitle, getDefaultSeries, getDefaultTrendLines, getDefaultTargetLine, @@ -1876,7 +2389,7 @@ } trendLineFields.push(regressionKey); - xResponse.metaData.names[regressionKey] = DV.i18n.trend + ' (' + xResponse.metaData.names[failSafeColumnIds[i]] + ')'; + xResponse.metaData.names[regressionKey] = DV.i18n.trend + (ns.dashboard ? '' : ' (' + xResponse.metaData.names[failSafeColumnIds[i]] + ')'); } } } @@ -2007,7 +2520,7 @@ labelRotation = 0, titleFont = 'bold 12px ' + conf.chart.style.fontFamily, titleColor = 'black', - + typeConf = conf.finals.chart, minimum = store.getMinimum(), maximum, @@ -2050,13 +2563,13 @@ grid: { odd: { opacity: 1, - stroke: '#aaa', - 'stroke-width': 0.1 + stroke: '#000', + 'stroke-width': 0.03 }, even: { opacity: 1, - stroke: '#aaa', - 'stroke-width': 0.1 + stroke: '#000', + 'stroke-width': 0.03 } } }; @@ -2091,7 +2604,7 @@ // label labelColor = style.labelColor || labelColor; - + if (style.labelFont) { labelFont = style.labelFont; } @@ -2108,7 +2621,7 @@ // title titleColor = style.titleColor || titleColor; - + if (style.titleFont) { titleFont = style.titleFont; } @@ -2135,7 +2648,7 @@ labelRotation = 315, titleFont = 'bold 12px ' + conf.chart.style.fontFamily, titleColor = 'black', - + axis = { type: 'Category', position: 'bottom', @@ -2146,7 +2659,7 @@ }, labelTitle: {} }; - + if (xLayout.domainAxisTitle) { axis.title = xLayout.domainAxisTitle; } @@ -2157,7 +2670,7 @@ // label labelColor = style.labelColor || labelColor; - + if (style.labelFont) { labelFont = style.labelFont; } @@ -2174,7 +2687,7 @@ // title titleColor = style.titleColor || titleColor; - + if (style.titleFont) { titleFont = style.titleFont; } @@ -2195,6 +2708,53 @@ return axis; }; + getFormatedSeriesTitle = function(titles) { + var itemLength = ns.dashboard ? 23 : 30, + charLength = ns.dashboard ? 5 : 6, + numberOfItems = titles.length, + numberOfChars, + totalItemLength = numberOfItems * itemLength, + //minLength = 5, + maxLength = support.prototype.array.getMaxLength(titles), + fallbackLength = 10, + maxWidth = ns.app.centerRegion.getWidth(), + width, + validateTitles; + + getValidatedTitles = function(titles, len) { + var numberOfItems = titles.length, + newTitles, + fallbackTitles; + + fallbackLength = len < fallbackLength ? len : fallbackLength; + + for (var i = len, width; i > 0; i--) { + newTitles = []; + + for (var j = 0, title, numberOfChars, newTitle; j < titles.length; j++) { + title = titles[j]; + + newTitles.push(title.length > i ? (title.slice(0, i) + '..') : title); + } + + numberOfChars = newTitles.join('').length; + width = totalItemLength + (numberOfChars * charLength); + + if (i === fallbackLength) { + fallbackTitles = Ext.clone(newTitles); + } + + if (width < maxWidth) { + return newTitles; + } + } + + return fallbackTitles; + }; + + return getValidatedTitles(titles, maxLength); + }; + getDefaultSeriesTitle = function(store) { var a = []; @@ -2206,19 +2766,40 @@ id = failSafeColumnIdMap[store.rangeFields[i]]; name = xResponse.metaData.names[id]; - if (Ext.isObject(xLayout.legendStyle) && Ext.isNumber(xLayout.legendStyle.labelMaxLength)) { - var mxl = parseInt(xLayout.legendStyle.labelMaxLength); + //if (Ext.isString(name) && Ext.isObject(xLayout.legendStyle) && Ext.isNumber(xLayout.legendStyle.labelMaxLength)) { + //var mxl = parseInt(xLayout.legendStyle.labelMaxLength); - if (Ext.isNumber(mxl)) { - name = name.substr(0, mxl) + '..'; - } - } + //name = name.length > mxl ? name.substr(0, mxl) + '..' : name; + //} a.push(name); } } - return a; + return getFormatedSeriesTitle(a); + }; + + getPieSeriesTitle = function(store) { + var a = []; + + if (Ext.isObject(xLayout.legendStyle) && Ext.isArray(xLayout.legendStyle.labelNames)) { + return xLayout.legendStyle.labelNames; + } + else { + var id = store.domainFields[0]; + + store.each( function(r) { + a.push(r.data[id]); + + //if (Ext.isString(name) && Ext.isObject(xLayout.legendStyle) && Ext.isNumber(xLayout.legendStyle.labelMaxLength)) { + //var mxl = parseInt(xLayout.legendStyle.labelMaxLength); + + //name = name.length > mxl ? name.substr(0, mxl) + '..' : name; + //} + }); + } + + return getFormatedSeriesTitle(a); }; getDefaultSeries = function(store) { @@ -2248,7 +2829,7 @@ // label labelColor = style.labelColor || labelColor; - + if (style.labelFont) { labelFont = style.labelFont; } @@ -2257,8 +2838,8 @@ labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px '; labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily; } - } - + } + main.label = { display: 'outside', 'text-anchor': 'middle', @@ -2324,7 +2905,7 @@ var title = (Ext.isString(xLayout.targetLineTitle) ? xLayout.targetLineTitle : DV.i18n.target) + ' (' + xLayout.targetLineValue + ')', ls = xLayout.legendStyle; return ls && Ext.isNumber(ls.labelMaxLength) ? title.substr(0, ls.labelMaxLength) + '..' : title; - }() + }() }; }; @@ -2345,7 +2926,7 @@ var title = (Ext.isString(xLayout.baseLineTitle) ? xLayout.baseLineTitle : DV.i18n.base) + ' (' + xLayout.baseLineValue + ')', ls = xLayout.legendStyle; return ls && Ext.isNumber(ls.labelMaxLength) ? title.substr(0, ls.labelMaxLength) + '..' : title; - }() + }() }; }; @@ -2356,7 +2937,7 @@ renderer: function(si, item) { if (item.value) { var value = item.value[1] === '0.0' ? '-' : item.value[1]; - this.update('<div style="text-align:center"><div style="font-size:17px; font-weight:bold">' + value + '</div><div style="font-size:10px">' + si.data[conf.finals.data.domain] + '</div></div>'); + this.update('<div style="font-size:17px; font-weight:bold">' + value + '</div><div style="font-size:10px">' + si.data[conf.finals.data.domain] + '</div>'); } } }; @@ -2376,51 +2957,46 @@ }; getDefaultLegend = function(store, chartConfig) { - var itemLength = 30, - charLength = 6, + var itemLength = ns.dashboard ? 24 : 30, + charLength = ns.dashboard ? 4 : 6, numberOfItems = 0, numberOfChars = 0, - str = '', width, isVertical = false, labelFont = '11px ' + conf.chart.style.fontFamily, + labelColor = 'black'; position = 'top', padding = 0, positions = ['top', 'right', 'bottom', 'left'], - series = chartConfig.series; - - if (xLayout.type === conf.finals.chart.pie) { - numberOfItems = store.getCount(); - store.each(function(r) { - str += r.data[store.domainFields[0]]; - }); - } - else { - for (var i = 0, title; i < series.length; i++) { - title = series[i].title; - - if (Ext.isString(title)) { - numberOfItems += 1; - numberOfChars += title.length; - } - else if (Ext.isArray(title)) { - numberOfItems += title.length; - numberOfChars += title.toString().split(',').join('').length; - } + series = chartConfig.series, + labelMarkerSize = xLayout.legendStyle && xLayout.legendStyle.labelMarkerSize ? xLayout.legendStyle.labelMarkerSize : null, + chartConfig; + + for (var i = 0, title; i < series.length; i++) { + title = series[i].title; + + if (Ext.isString(title)) { + numberOfItems += 1; + numberOfChars += title.length; + } + else if (Ext.isArray(title)) { + numberOfItems += title.length; + numberOfChars += title.toString().split(',').join('').length; } } width = (numberOfItems * itemLength) + (numberOfChars * charLength); - - if (width > ns.app.centerRegion.getWidth() - 2) { - isVertical = true; + + if (width > ns.app.centerRegion.getWidth() - 6) { position = 'right'; } // style if (Ext.isObject(xLayout.legendStyle)) { var style = xLayout.legendStyle; - + + labelColor = style.labelColor || labelColor; + if (Ext.Array.contains(positions, style.position)) { position = style.position; } @@ -2431,23 +3007,32 @@ else { labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal '; labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px '; - labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily; + labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily; } } // padding if (position === 'right') { - padding = 5; + padding = 3; } - return Ext.create('Ext.chart.Legend', { + // chart + chartConfig = { position: position, isVertical: isVertical, - labelFont: labelFont, boxStroke: '#ffffff', boxStrokeWidth: 0, - padding: padding - }); + padding: padding, + itemSpacing: 3, + labelFont: labelFont, + labelColor: labelColor + }; + + if (labelMarkerSize) { + chartConfig.labelMarkerSize = labelMarkerSize; + } + + return Ext.create('Ext.chart.Legend', chartConfig); }; getDefaultChartTitle = function(store) { @@ -2504,16 +3089,19 @@ font: titleFont, fill: titleColor, height: 20, - y: 20 + y: ns.dashboard ? 7 : 20 }); }; getDefaultChartSizeHandler = function() { + var width = ns.app.centerRegion.getWidth(), + height = ns.app.centerRegion.getHeight(); + return function() { this.animate = false; - this.setWidth(ns.app.centerRegion.getWidth() - 15); - this.setHeight(ns.app.centerRegion.getHeight() - 40); - this.animate = true; + this.setWidth(ns.dashboard ? width : width - 15); + this.setHeight(ns.dashboard ? height : height - 40); + this.animate = !ns.dashboard; }; }; @@ -2546,12 +3134,22 @@ getDefaultChart = function(config) { var chart, store = config.store || {}, + width = ns.app.centerRegion.getWidth(), + height = ns.app.centerRegion.getHeight(), + isLineBased = Ext.Array.contains(['line', 'area'], xLayout.type), defaultConfig = { - animate: true, + //animate: true, + animate: false, shadow: false, - insetPadding: 35, - width: ns.app.centerRegion.getWidth() - 15, - height: ns.app.centerRegion.getHeight() - 40, + insetPadding: ns.dashboard ? 17 : 35, + insetPaddingObject: { + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : (isLineBased ? 25 : 15), + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : (isLineBased ? 70 : 50) + }, + width: ns.dashboard ? width : width - 15, + height: ns.dashboard ? height : height - 40, theme: 'dv1' }; @@ -2560,20 +3158,23 @@ defaultConfig.legend = getDefaultLegend(store, config); if (defaultConfig.legend.position === 'right') { - defaultConfig.insetPadding = 40; + defaultConfig.insetPaddingObject.top = ns.dashboard ? 22 : 40; + defaultConfig.insetPaddingObject.right = ns.dashboard ? 5 : 40; } } // title - if (!xLayout.hideTitle) { + if (xLayout.hideTitle) { + defaultConfig.insetPadding = ns.dashboard ? 1 : 10; + defaultConfig.insetPaddingObject.top = ns.dashboard ? 3 : 10; + } + else { defaultConfig.items = [getDefaultChartTitle(store)]; } - else { - defaultConfig.insetPadding = 10; - } Ext.apply(defaultConfig, config); + // chart chart = Ext.create('Ext.chart.Chart', defaultConfig); chart.setChartSize = getDefaultChartSizeHandler(); @@ -2585,7 +3186,7 @@ chart.setTitlePosition(); }; - chart.on('afterrender', function() { + chart.on('resize', function() { chart.setTitlePosition(); }); @@ -2744,7 +3345,7 @@ }, markerConfig: { type: 'circle', - radius: 4 + radius: ns.dashboard ? 3 : 4 }, tips: getDefaultTips(), title: seriesTitles[i] @@ -2760,7 +3361,7 @@ series.push(line); } - // Options, theme colors + // options, theme colors if (xLayout.showTrendLine) { series = getDefaultTrendLines(store).concat(series); @@ -2779,7 +3380,7 @@ colors.push('#051a2e'); } - // Theme + // theme Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, { constructor: function(config) { Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({ @@ -2846,24 +3447,43 @@ field: conf.finals.data.domain }; - // Label + // label if (xLayout.showValues) { + var labelFont = conf.chart.style.fontFamily, + labelColor; + + if (Ext.isObject(xLayout.seriesStyle)) { + var style = xLayout.seriesStyle; + + // color + labelColor = style.labelColor || labelColor; + + if (style.labelFont) { + labelFont = style.labelFont; + } + else { + labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal '; + labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px '; + labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily; + } + } + label.display = 'middle'; - label.contrast = true; - label.font = '14px ' + conf.chart.style.fontFamily; + label.contrast = !labelColor; + label.font = labelFont; + label.fill = labelColor; label.renderer = function(value) { var record = store.getAt(store.findExact(conf.finals.data.domain, value)); return record.data[store.rangeFields[0]]; }; } - // Series + // series series = [{ type: 'pie', field: store.rangeFields[0], - donut: 7, + donut: 5, showInLegend: true, - shadowAttributes: false, highlight: { segment: { margin: 5 @@ -2880,10 +3500,12 @@ renderer: function(item) { this.update('<div style="text-align:center"><div style="font-size:17px; font-weight:bold">' + item.data[store.rangeFields[0]] + '</div><div style="font-size:10px">' + item.data[conf.finals.data.domain] + '</div></div>'); } - } + }, + shadowAttributes: false, + title: getPieSeriesTitle(store) }]; - // Theme + // theme colors = conf.chart.theme.dv1.slice(0, xResponse.nameHeaderMap[xLayout.rowDimensionNames[0]].ids.length); Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, { @@ -2895,17 +3517,18 @@ } }); - // Chart + // chart chart = getDefaultChart({ store: store, - series: series + series: series, + insetPaddingObject: { + top: 15, + right: 2, + bottom: 13, + left: 7 + } }); - //chart.legend.position = 'right'; - //chart.legend.isVertical = true; - chart.insetPadding = 40; - chart.shadow = true; - return chart; }; @@ -2914,6 +3537,8 @@ axes = [], series = [], seriesTitles = getDefaultSeriesTitle(store), + labelFont = 'normal 9px sans-serif', + labelColor = '#333', chart; // axes @@ -2949,23 +3574,41 @@ series.push(obj); } + // style + if (Ext.isObject(xLayout.seriesStyle)) { + var style = xLayout.seriesStyle; + + // label + labelColor = style.labelColor || labelColor; + + if (style.labelFont) { + labelFont = style.labelFont; + } + else { + labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal '; + labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '9px '; + labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily; + } + } + + // chart chart = getDefaultChart({ store: store, axes: axes, series: series, - theme: 'Category2' + theme: 'Category2', + insetPaddingObject: { + top: 20, + right: 2, + bottom: 15, + left: 7 + }, + seriesStyle: { + labelColor: labelColor, + labelFont: labelFont + } }); - chart.insetPadding = 40; - chart.height = ns.app.centerRegion.getHeight() - 80; - - chart.setChartSize = function() { - this.animate = false; - this.setWidth(ns.app.centerRegion.getWidth()); - this.setHeight(ns.app.centerRegion.getHeight() - 80); - this.animate = true; - }; - return chart; }; @@ -3014,12 +3657,13 @@ width: ns.app.centerRegion.getWidth(), height: ns.app.centerRegion.getHeight() * 0.6, store: store, - insetPadding: 100, + insetPadding: ns.dashboard ? 50 : 100, theme: null, - animate: { - easing: 'elasticIn', - duration: 1000 - } + //animate: { + //easing: 'elasticIn', + //duration: 1000 + //} + animate: false }); if (xLayout.showValues) { @@ -3034,10 +3678,10 @@ } chart.setChartSize = function() { - this.animate = false; + //this.animate = false; this.setWidth(ns.app.centerRegion.getWidth()); this.setHeight(ns.app.centerRegion.getHeight() * 0.6); - this.animate = true; + //this.animate = true; }; chart.setTitlePosition = function() { === modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/chart.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/chart.js 2015-03-28 16:52:19 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/chart.js 2015-03-30 13:36:53 +0000 @@ -237,7 +237,7 @@ markerConfig, label, mask, radius, toggle = false, seriesStyle = Ext.apply(series.seriesStyle, series.style), - labelMarkerSize = legend.labelMarkerSize || 12; + labelMarkerSize = legend.labelMarkerSize || 10; function getSeriesProp(name) { var val = series[name]; @@ -246,7 +246,7 @@ label = me.add('label', surface.add({ type: 'text', - x: 0, + x: 30, y: 0, zIndex: z || 0, font: legend.labelFont, @@ -3193,16 +3193,17 @@ store = config.store || {}, width = ns.app.centerRegion.getWidth(), height = ns.app.centerRegion.getHeight(), + isLineBased = Ext.Array.contains(['line', 'area'], xLayout.type), defaultConfig = { //animate: true, animate: false, shadow: false, insetPadding: ns.dashboard ? 17 : 35, insetPaddingObject: { - top: 10, - right: 3, - bottom: 2, - left: 7 + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : 10, + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : 17 }, width: ns.dashboard ? width : width - 15, height: ns.dashboard ? height : height - 40, === modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js 2015-03-28 16:52:19 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js 2015-03-30 13:36:53 +0000 @@ -237,7 +237,7 @@ markerConfig, label, mask, radius, toggle = false, seriesStyle = Ext.apply(series.seriesStyle, series.style), - labelMarkerSize = legend.labelMarkerSize || 12; + labelMarkerSize = legend.labelMarkerSize || 10; function getSeriesProp(name) { var val = series[name]; @@ -246,7 +246,7 @@ label = me.add('label', surface.add({ type: 'text', - x: 0, + x: 30, y: 0, zIndex: z || 0, font: legend.labelFont, @@ -3639,10 +3639,10 @@ shadow: false, insetPadding: ns.dashboard ? 17 : 35, insetPaddingObject: { - top: 10, - right: isLineBased ? 5 : 3, - bottom: 2, - left: isLineBased ? 15 : 7 + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : 10, + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : 17 }, width: ns.dashboard ? width : width - 15, height: ns.dashboard ? height : height - 40, === modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/chart.js' --- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/chart.js 2015-03-28 16:52:19 +0000 +++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/chart.js 2015-03-30 13:36:53 +0000 @@ -237,7 +237,7 @@ markerConfig, label, mask, radius, toggle = false, seriesStyle = Ext.apply(series.seriesStyle, series.style), - labelMarkerSize = legend.labelMarkerSize || 12; + labelMarkerSize = legend.labelMarkerSize || 10; function getSeriesProp(name) { var val = series[name]; @@ -246,7 +246,7 @@ label = me.add('label', surface.add({ type: 'text', - x: 0, + x: 30, y: 0, zIndex: z || 0, font: legend.labelFont, @@ -3186,16 +3186,17 @@ store = config.store || {}, width = ns.app.centerRegion.getWidth(), height = ns.app.centerRegion.getHeight(), + isLineBased = Ext.Array.contains(['line', 'area'], xLayout.type), defaultConfig = { //animate: true, animate: false, shadow: false, insetPadding: ns.dashboard ? 17 : 35, insetPaddingObject: { - top: 12, - right: 3, - bottom: 2, - left: 7 + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : 10, + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : 17 }, width: ns.dashboard ? width : width - 15, height: ns.dashboard ? height : height - 40, === modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js' --- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js 2015-03-28 16:52:19 +0000 +++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js 2015-03-30 13:36:53 +0000 @@ -237,7 +237,7 @@ markerConfig, label, mask, radius, toggle = false, seriesStyle = Ext.apply(series.seriesStyle, series.style), - labelMarkerSize = legend.labelMarkerSize || 12; + labelMarkerSize = legend.labelMarkerSize || 10; function getSeriesProp(name) { var val = series[name]; @@ -246,7 +246,7 @@ label = me.add('label', surface.add({ type: 'text', - x: 0, + x: 30, y: 0, zIndex: z || 0, font: legend.labelFont, @@ -3632,10 +3632,10 @@ shadow: false, insetPadding: ns.dashboard ? 17 : 35, insetPaddingObject: { - top: 10, - right: isLineBased ? 5 : 3, - bottom: 2, - left: isLineBased ? 15 : 7 + top: ns.dashboard ? 12 : 22, + right: ns.dashboard ? (isLineBased ? 5 : 3) : 10, + bottom: ns.dashboard ? 2 : 10, + left: ns.dashboard ? (isLineBased ? 15 : 7) : 17 }, width: ns.dashboard ? width : width - 15, height: ns.dashboard ? height : height - 40,
_______________________________________________ Mailing list: https://launchpad.net/~dhis2-devs Post to : dhis2-devs@lists.launchpad.net Unsubscribe : https://launchpad.net/~dhis2-devs More help : https://help.launchpad.net/ListHelp