diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js |
first commit
Diffstat (limited to 'www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js')
-rw-r--r-- | www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js new file mode 100644 index 00000000..da2ebb63 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js @@ -0,0 +1,280 @@ +(function (angular, $, _) { + + + // FIXME: This code is long and hasn't been fully working for me, but I've moved it into a spot + // where it at least fits in a bit better. + + // example: <div crm-mailing-ab-stats="{split_count: 6, criteria:'Open'}" crm-abtest="myabtest" /> + // options (see also: Mailing.graph_stats API) + // - split_count: int + // - criteria: string + // - target_date: string, date + // - target_url: string + angular.module('crmMailingAB').directive('crmMailingAbStats', function (crmApi, $parse) { + return { + scope: { + crmMailingAbStats: '@', + crmAbtest: '@' + }, + template: '<div class="crm-mailing-ab-stats"></div>', + link: function (scope, element, attrs) { + var abtestModel = $parse(attrs.crmAbtest); + var optionModel = $parse(attrs.crmMailingAbStats); + var options = angular.extend({}, optionModel(scope.$parent), { + criteria: 'Open', // e.g. 'Open', 'Total Unique Clicks' + split_count: 5 + }); + + scope.$watch(attrs.crmAbtest, refresh); + function refresh() { + var abtest = abtestModel(scope.$parent); + if (!abtest) { + console.log('failed to draw stats - missing abtest'); + return; + } + + scope.graph_data = [ + {}, + {}, + {}, + {}, + {} + ]; + var keep_cnt = 0; + + for (var i = 1; i <= options.split_count; i++) { + var result = crmApi('MailingAB', 'graph_stats', { + id: abtest.ab.id, + target_date: abtest.ab.declare_winning_time ? abtest.ab.declare_winning_time : 'now', + target_url: null, // FIXME + criteria: options.criteria, + split_count: options.split_count, + split_count_select: i + }); + /*jshint -W083 */ + result.then(function (data) { + var temp = 0; + keep_cnt++; + for (var key in data.values.A) { + temp = key; + } + var t = data.values.A[temp].time.split(" "); + var m = t[0]; + var year = t[2]; + var day = t[1].substr(0, t[1].length - 3); + var t1, hur, hour, min; + if (_.isEmpty(t[3])) { + t1 = t[4].split(":"); + hur = t1[0]; + if (t[5] == "AM") { + hour = hur; + if (hour == 12) { + hour = 0; + } + } + if (t[5] == "PM") { + hour = parseInt(hur) + 12; + } + min = t1[1]; + } + else { + t1 = t[3].split(":"); + hur = t1[0]; + if (t[4] == "AM") { + hour = hur; + if (hour == 12) { + hour = 0; + } + } + if (t[4] == "PM") { + hour = parseInt(hur) + 12; + } + min = t1[1]; + } + var month = 0; + switch (m) { + case "January": + month = 0; + break; + case "February": + month = 1; + break; + case "March": + month = 2; + break; + case "April": + month = 3; + break; + case "May": + month = 4; + break; + case "June": + month = 5; + break; + case "July": + month = 6; + break; + case "August": + month = 7; + break; + case "September": + month = 8; + break; + case "October": + month = 9; + break; + case "November": + month = 10; + break; + case "December": + month = 11; + break; + + } + var tp = new Date(year, month, day, hour, min, 0, 0); + scope.graph_data[temp - 1] = { + time: tp, + x: data.values.A[temp].count, + y: data.values.B[temp].count + }; + + if (keep_cnt == options.split_count) { + scope.graphload = true; + data = scope.graph_data; + + // set up a colour variable + var color = d3.scale.category10(); + + // map one colour each to x, y and z + // keys grabs the key value or heading of each key value pair in the json + // but not time + color.domain(d3.keys(data[0]).filter(function (key) { + return key !== "time"; + })); + + // create a nested series for passing to the line generator + // it's best understood by console logging the data + var series = color.domain().map(function (name) { + return { + name: name, + values: data.map(function (d) { + return { + time: d.time, + score: +d[name] + }; + }) + }; + }); + + // Set the dimensions of the canvas / graph + var margin = { + top: 30, + right: 20, + bottom: 40, + left: 75 + }, + width = 550 - margin.left - margin.right, + height = 350 - margin.top - margin.bottom; + + // Set the ranges + //var x = d3.time.scale().range([0, width]).domain([0,10]); + var x = d3.time.scale().range([0, width]); + var y = d3.scale.linear().range([height, 0]); + + // Define the axes + var xAxis = d3.svg.axis().scale(x) + .orient("bottom").ticks(10); + + var yAxis = d3.svg.axis().scale(y) + .orient("left").ticks(5); + + // Define the line + // Note you plot the time / score pair from each key you created earlier + var valueline = d3.svg.line() + .x(function (d) { + return x(d.time); + }) + .y(function (d) { + return y(d.score); + }); + + // Adds the svg canvas + var svg = d3.select($('.crm-mailing-ab-stats', element)[0]) + .append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + // Scale the range of the data + x.domain(d3.extent(data, function (d) { + return d.time; + })); + + // note the nested nature of this you need to dig an additional level + y.domain([ + d3.min(series, function (c) { + return d3.min(c.values, function (v) { + return v.score; + }); + }), + d3.max(series, function (c) { + return d3.max(c.values, function (v) { + return v.score; + }); + }) + ]); + svg.append("text") // text label for the x axis + .attr("x", width / 2) + .attr("y", height + margin.bottom) + .style("text-anchor", "middle") + .text("Time"); + + svg.append("text") // text label for the x axis + .style("text-anchor", "middle") + .text(scope.winnercriteria).attr("transform",function (d) { + return "rotate(-90)"; + }).attr("x", -height / 2) + .attr("y", -30); + + // create a variable called series and bind the date + // for each series append a g element and class it as series for css styling + series = svg.selectAll(".series") + .data(series) + .enter().append("g") + .attr("class", "series"); + + // create the path for each series in the variable series i.e. x, y and z + // pass each object called x, y nad z to the lne generator + series.append("path") + .attr("class", "line") + .attr("d", function (d) { + // console.log(d); // to see how d3 iterates through series + return valueline(d.values); + }) + .style("stroke", function (d) { + return color(d.name); + }); + + // Add the X Axis + svg.append("g") // Add the X Axis + .attr("class", "x axis") + .attr("transform", "translate(0," + height + ")") + .call(xAxis) + .selectAll("text") + .attr("transform", function (d) { + return "rotate(-30)"; + }); + + // Add the Y Axis + svg.append("g") // Add the Y Axis + .attr("class", "y axis") + .call(yAxis); + } + }); + } + } + } // link() + }; + }); +})(angular, CRM.$, CRM._); |