First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
280
sites/all/modules/civicrm/ang/crmMailingAB/Stats.js
Normal file
280
sites/all/modules/civicrm/ang/crmMailingAB/Stats.js
Normal file
|
|
@ -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._);
|
||||
Loading…
Add table
Add a link
Reference in a new issue