File indexing completed on 2024-12-22 05:34:40

0001 !(function (d3) {
0002 
0003             var parseTime = d3.timeParse("%Y%m%d");
0004                     
0005 
0006                 d3.json("/backend/index/getproductdayly?project_id="+window.project_id, function(error, data) {                                            
0007                 if (error) throw error;
0008 
0009              
0010                 data = data.results;   
0011                 if(!data){
0012                      $("#topDownloadsPerMonthTabContainer_DetailDayly").text('no data found!');
0013                     return;
0014                 }
0015 
0016                 data.forEach(function (d) {                   
0017                    d.year = parseTime(d.yearmonth);
0018                    d.amount = +d.amount;                      
0019                 });                
0020                 var title =project_id+'_daily';      
0021                 var chartColumns ={
0022                     [title]: {column: 'amount'}                       
0023                 };
0024 
0025                            
0026                 var chart = makeLineChart_date(data, 'year',chartColumns , {xAxis: 'Month', yAxis: 'Amount'});
0027 
0028                 $('#topDownloadsPerMonthTabContainer_DetailDayly').empty();
0029                 chart.bind("#topDownloadsPerMonthTabContainer_DetailDayly");
0030                 chart.render();
0031 
0032             });
0033 
0034 
0035 })(d3);
0036 
0037 
0038 
0039 
0040 function makeLineChart_date(dataset, xName, yObjs, axisLables) {
0041     var chartObj = {};
0042   
0043     var color = d3.scaleOrdinal().range(["#1F77B4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c"
0044         ,"#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"
0045         ,"#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f"
0046         ,"#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"
0047         ,"#393b79","#5254a3","#6b6ecf","#9c9ede","#637939"
0048         ,"#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52"
0049         ,"#ad494a","#d6616b","#7b4173","#a55194","#ce6dbd"]);
0050     chartObj.xAxisLable = axisLables.xAxis;
0051     chartObj.yAxisLable = axisLables.yAxis;
0052     /*
0053      yObjsects format:
0054      {y1:{column:'',name:'name',color:'color'},y2}
0055      */
0056 
0057     chartObj.data = dataset;
0058     chartObj.margin = {top: 15, right: 60, bottom: 30, left: 50};
0059     chartObj.width = 650 - chartObj.margin.left - chartObj.margin.right;
0060     chartObj.height = 480 - chartObj.margin.top - chartObj.margin.bottom;
0061 
0062 // So we can pass the x and y as strings when creating the function
0063     chartObj.xFunct = function(d){return d[xName]};
0064  
0065 // For each yObjs argument, create a yFunction
0066     function getYFn(column) {
0067         return function (d) {
0068             return d[column];
0069         };
0070     }
0071 
0072 // Object instead of array
0073     chartObj.yFuncts = [];
0074     for (var y  in yObjs) {
0075         yObjs[y].name = y;
0076         yObjs[y].yFunct = getYFn(yObjs[y].column); //Need this  list for the ymax function
0077         chartObj.yFuncts.push(yObjs[y].yFunct);
0078     }
0079 
0080 //Formatter functions for the axes
0081     chartObj.formatAsNumber = d3.format(".0f");
0082     chartObj.formatAsDecimal = d3.format(".2f");
0083     chartObj.formatAsCurrency = d3.format("$.2f");
0084     chartObj.formatAsYYYYMM = d3.timeFormat("%Y-%m-%d");
0085     
0086     chartObj.formatAsFloat = function (d) {
0087         if (d % 1 !== 0) {
0088             return d3.format(".2f")(d);
0089         } else {
0090             return d3.format(".0f")(d);
0091         }
0092         
0093     };
0094 
0095     chartObj.xFormatter = chartObj.formatAsYYYYMM;
0096     chartObj.yFormatter = chartObj.formatAsFloat;
0097 
0098     chartObj.bisectYear = d3.bisector(chartObj.xFunct).left; //< Can be overridden in definition
0099 
0100 //Create scale functions
0101     chartObj.xScale = d3.scaleLinear().range([0, chartObj.width]).domain(d3.extent(chartObj.data, chartObj.xFunct)); 
0102     //chartObj.xScale = d3.scaleTime().range([0, chartObj.width]).domain(d3.extent(chartObj.data, chartObj.xFunct));                                                  
0103 
0104 // Get the max of every yFunct
0105     chartObj.max = function (fn) {
0106         return d3.max(chartObj.data, fn);
0107     };
0108     chartObj.yScale = d3.scaleLinear().range([chartObj.height, 0]).domain([0, d3.max(chartObj.yFuncts.map(chartObj.max))]);
0109 
0110     chartObj.formatAsYear = d3.format("");
0111 
0112 //Create axis
0113 
0114     chartObj.xAxis  = d3.axisBottom(chartObj.xScale).tickFormat(chartObj.xFormatter);
0115     chartObj.yAxis = d3.axisLeft(chartObj.yScale).tickFormat(chartObj.yFormatter);
0116 
0117 
0118 // Build line building functions
0119     function getYScaleFn(yObj) {
0120         return function (d) {
0121             return chartObj.yScale(yObjs[yObj].yFunct(d));
0122         };
0123     }
0124 
0125     for (var yObj in yObjs) {
0126         yObjs[yObj].line = d3.line().x(function (d) {
0127             return chartObj.xScale(chartObj.xFunct(d));
0128         }).y(getYScaleFn(yObj));
0129     }
0130     
0131 
0132     chartObj.svg;
0133 
0134 // Change chart size according to window size
0135     chartObj.update_svg_size = function () {
0136         chartObj.width = parseInt(chartObj.chartDiv.style("width"), 10) - (chartObj.margin.left + chartObj.margin.right);
0137 
0138         chartObj.height = parseInt(chartObj.chartDiv.style("height"), 10) - (chartObj.margin.top + chartObj.margin.bottom);
0139 
0140         /* Update the range of the scale with new width/height */
0141         chartObj.xScale.range([0, chartObj.width]);
0142         chartObj.yScale.range([chartObj.height, 0]);
0143 
0144         if (!chartObj.svg) {return false;}
0145 
0146         /* Else Update the axis with the new scale */
0147         chartObj.svg.select('.x.axis').attr("transform", "translate(0," + chartObj.height + ")").call(chartObj.xAxis);
0148         chartObj.svg.select('.x.axis .label').attr("x", chartObj.width / 2);
0149 
0150         chartObj.svg.select('.y.axis').call(chartObj.yAxis);
0151         chartObj.svg.select('.y.axis .label').attr("x", -chartObj.height / 2);
0152 
0153         /* Force D3 to recalculate and update the line */
0154         for (var y  in yObjs) {
0155             yObjs[y].path.attr("d", yObjs[y].line);
0156         }
0157         
0158 
0159         d3.selectAll(".focus.line").attr("y2", chartObj.height);
0160 
0161         chartObj.chartDiv.select('svg').attr("width", chartObj.width + (chartObj.margin.left + chartObj.margin.right)).attr("height", chartObj.height + (chartObj.margin.top + chartObj.margin.bottom));
0162 
0163         chartObj.svg.select(".overlay").attr("width", chartObj.width).attr("height", chartObj.height);
0164         return chartObj;
0165     };
0166 
0167     chartObj.bind = function (selector) {
0168         chartObj.mainDiv = d3.select(selector);
0169         // Add all the divs to make it centered and responsive
0170         chartObj.mainDiv.append("div").attr("class", "inner-wrapper").append("div").attr("class", "outer-box").append("div").attr("class", "inner-box");
0171         chartSelector = selector + " .inner-box";
0172         chartObj.chartDiv = d3.select(chartSelector);
0173         d3.select(window).on('resize.' + chartSelector, chartObj.update_svg_size);
0174         chartObj.update_svg_size();
0175         return chartObj;
0176     };
0177 
0178 // Render the chart
0179     chartObj.render = function () {
0180         //Create SVG element
0181         chartObj.svg = chartObj.chartDiv.append("svg").attr("class", "chart-area").attr("width", chartObj.width + (chartObj.margin.left + chartObj.margin.right)).attr("height", chartObj.height + (chartObj.margin.top + chartObj.margin.bottom)).append("g").attr("transform", "translate(" + chartObj.margin.left + "," + chartObj.margin.top + ")");
0182 
0183         // Draw Lines
0184         for (var y  in yObjs) {
0185             yObjs[y].path = chartObj.svg.append("path").datum(chartObj.data).attr("class", "line").attr("d", yObjs[y].line).style("stroke", color(y)).attr("data-series", y).on("mouseover", function () {
0186                 focus.style("display", null);
0187             }).on("mouseout", function () {
0188                 focus.transition().delay(700).style("display", "none");
0189             }).on("mousemove", mousemove);
0190         }
0191         
0192 
0193         // .selectAll("text")
0194         //     .attr("y", 0)
0195         //     .attr("x", 9)
0196         //     .attr("dy", ".35em")
0197         //     .attr("transform", "rotate(90)")
0198         //     .style("text-anchor", "start")
0199 
0200         // Draw Axis
0201         chartObj.svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + chartObj.height + ")").call(chartObj.xAxis).append("text").attr("class", "label").attr("x", chartObj.width / 2).attr("y", 30).style("text-anchor", "middle").text(chartObj.xAxisLable);
0202             
0203 
0204 
0205         chartObj.svg.append("g").attr("class", "y axis").call(chartObj.yAxis).append("text").attr("class", "label").attr("transform", "rotate(-90)").attr("y", -42).attr("x", -chartObj.height / 2).attr("dy", ".71em").style("text-anchor", "middle").text(chartObj.yAxisLable);
0206 
0207         //Draw tooltips
0208         var focus = chartObj.svg.append("g").attr("class", "focus").style("display", "none");
0209 
0210 
0211         for (var y  in yObjs) {
0212             yObjs[y].tooltip = focus.append("g");
0213             yObjs[y].tooltip.append("circle").attr("r", 5);
0214             yObjs[y].tooltip.append("rect").attr("x", 8).attr("y","-5").attr("width",22).attr("height",'0.75em');
0215             yObjs[y].tooltip.append("text").attr("x", 9).attr("dy", ".35em");
0216         }
0217 
0218         // Year label
0219         focus.append("text").attr("class", "focus year").attr("x", 9).attr("y", 7);
0220         // Focus line
0221         focus.append("line").attr("class", "focus line").attr("y1", 0).attr("y2", chartObj.height);
0222 
0223         //Draw legend
0224         var legend = chartObj.mainDiv.append('div').attr("class", "legend");
0225         for (var y  in yObjs) {
0226             series = legend.append('div');
0227             series.append('div').attr("class", "series-marker").style("background-color", color(y));
0228             series.append('p').text(y);
0229             yObjs[y].legend = series;
0230         }
0231 
0232         // Overlay to capture hover
0233         chartObj.svg.append("rect").attr("class", "overlay").attr("width", chartObj.width).attr("height", chartObj.height).on("mouseover", function () {
0234             focus.style("display", null);
0235         }).on("mouseout", function () {
0236             focus.style("display", "none");
0237         }).on("mousemove", mousemove);
0238 
0239         return chartObj;
0240         function mousemove() {
0241             
0242             var x0 = chartObj.xScale.invert(d3.mouse(this)[0]), i = chartObj.bisectYear(dataset, x0, 1), d0 = chartObj.data[i - 1], d1 = chartObj.data[i];
0243 
0244             try {
0245                 var d = x0 - chartObj.xFunct(d0) > chartObj.xFunct(d1) - x0 ? d1 : d0;
0246 
0247             } catch (e) {  console.log(e); return;}
0248             minY = chartObj.height;
0249             for (var y  in yObjs) {
0250                 yObjs[y].tooltip.attr("transform", "translate(" + chartObj.xScale(chartObj.xFunct(d)) + "," + chartObj.yScale(yObjs[y].yFunct(d)) + ")");
0251                 yObjs[y].tooltip.select("text").text(chartObj.yFormatter(yObjs[y].yFunct(d)));
0252                 minY = Math.min(minY, chartObj.yScale(yObjs[y].yFunct(d)));
0253             }
0254 
0255             focus.select(".focus.line").attr("transform", "translate(" + chartObj.xScale(chartObj.xFunct(d)) + ")").attr("y1", minY);
0256             focus.select(".focus.year").text("Yearmonth: " + chartObj.xFormatter(chartObj.xFunct(d)));
0257         }
0258 
0259     };
0260     return chartObj;
0261 }
0262 
0263