summaryrefslogtreecommitdiff
path: root/www/crm/wp-content/plugins/civicrm/civicrm/ang/crmMailingAB/Stats.js
diff options
context:
space:
mode:
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.js280
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._);