var width = parseInt(d3.select("#tescoChart").style("width")); var csvFile = "/wp-content/uploads/2015/04/0421-tesco-desktop-55367c2e0ce53.csv"; if (width<768) { var margin = { top: 25, right: 15, bottom: 25, left: 40 }; var pixelRatio = 8; } else { var margin = { top: 25, right: 25, bottom: 25, left: 40 }; var pixelRatio = 6; }; var width = parseInt(d3.select("#tescoChart").style("width")) - margin.left - margin.right, height = parseInt(d3.select("#tescoChart").style("height")) - margin.top - margin.bottom, parseDate = d3.time.format("%d/%m/%Y").parse, bisectDate = d3.bisector(function(d) { return parseDate(d.date); }).left; d3.csv(csvFile, function(error, ftseData) { ftseDataPerPixel = ftseData.length/width; ftseDataResampled = ftseData.filter(function(d, i) { if ((typeof d.text !== "undefined") || (i % Math.ceil(ftseDataPerPixel) == 0)) { return i; } }); var minDate = parseDate(ftseDataResampled[0].date), maxDate = parseDate(ftseDataResampled[ftseDataResampled.length - 1].date), lastRecord = ftseDataResampled[ftseDataResampled.length-1], firstRecord = ftseDataResampled[0], x = d3.time.scale() .domain(d3.extent(ftseDataResampled, function (d) { return parseDate(d.date); })) .range([0, width]), y = d3.scale.linear() .domain([150,500]).range([height, 0]) line = d3.svg.line() .x(function (d) { return x(parseDate(d.date)); }) .y(function (d) { return y(d.close); }); var make_x_axis = function () { if (width<568) { return d3.svg.axis().scale(x).orient("bottom").ticks(d3.time.months).tickFormat(d3.time.format("%b")); } else { return d3.svg.axis().scale(x).orient("bottom").ticks(8); } }, make_y_axis = function () { return d3.svg.axis().scale(y).orient("left").ticks(100); }; if (width<568) { xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(d3.time.months).tickFormat(d3.time.format("%b")); } else { xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(8); } yAxis = d3.svg.axis().scale(y).orient("left").ticks(10), zoom = d3.behavior.zoom().x(x).scaleExtent([1, 100]).on("zoom", zoomed); var toolTip = d3.select("body") .append("div") .attr("class", "tooltip") .style("opacity", 0); var sharePrice = d3.select("#tescoChart") .append("div") .attr("class", "sharePrice"); if (lastRecord.change > 0) { theColor = "green"; } else if (lastRecord.change < 0) { theColor = "red"; } else { theColor = "black"; } sharePrice.html( '

' + lastRecord.date + ': ' + lastRecord.close + 'p (' + lastRecord.change + '%)

');

var svg = d3.select('#tescoChart') .append("svg:svg") .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .append("svg:g") .attr("class","tescoChart") .attr("transform", "translate(" + margin.left + ",15)") .call(zoom);

var axes = svg.append("svg:g") .attr("class","axesGroup");

axes.append("svg:g") .attr("class", "x axis") .attr("transform", "translate(0, " + height + ")") .call(xAxis);

axes.append("g") .attr("class", "y axis") .call(yAxis);

axes.append("g") .attr("class", "x grid") .attr("transform", "translate(0," + height + ")") .call(make_x_axis() .tickSize(-height, 0, 0) .tickFormat(""));

axes.append("g") .attr("class", "y grid") .call(make_y_axis() .tickSize(-width, 0, 0) .tickFormat(""));

var ftseGraph = svg.append("g") .attr("class","ftseGraph");

var focus = ftseGraph.append("circle") .attr("r", 10.5) .attr("class", "focus") .style("display", "none");

ftseGraph.append("rect") .attr("class", "overlay") .attr("width", width) .attr("height", height) .style("fill", "none") .style("pointer-events", "all") .on("mouseover", function() { focus.style("display", null); }) .on("mouseout", function() { focus.style("display", "none"); if (lastRecord.change > 0) { theColor = "green"; } else if (lastRecord.change < 0) { theColor = "red"; } else { theColor = "black"; } sharePrice.html( '

' + lastRecord.date + ': ' + lastRecord.close + 'p (' + lastRecord.change + '%)

'); }) .on("mousemove", mousemove);

var clip = ftseGraph.append("svg:clipPath") .attr("id", "clip") .append("svg:rect") .attr("x", 0) .attr("y", 0) .attr("width", width) .attr("height", height);

var chartBody = ftseGraph.append("g") .attr("clip-path", "url(#clip)");

chartBody.append("svg:path") .datum(ftseDataResampled) .attr("class", "line") .attr("d", line);

var circles = chartBody.selectAll(".circ") .data(ftseDataResampled) .enter().append("circle") .attr("class", function(d) { if ((typeof d.size!= "undefined") && (d.size==3)) { return "circ major"; } else { return "circ"; } }) .attr("r", function(d) { if (typeof d.size!= "undefined") { return (d.size*pixelRatio); } else { return 0; } }) .attr("cx", function(d) { return x(parseDate(d.date)); }) .attr("cy", function(d) { return y(d.close); }) .on("mouseover", mouser) .on("mouseout", mouseGone);

var majors = svg.selectAll("circle.major"); majors.moveToFront();

function mouseGone() { focus.moveToBack(); toolTip.transition() .duration(500) .style("opacity", 1); toolTip.transition() .duration(200) .style("opacity", 0) }

function mousemove() { focus.style("display", null); var x0 = x.invert(d3.mouse(this)[0]), i = bisectDate(ftseDataResampled, x0, 1); d0 = ftseDataResampled[i - 1]; d1 = ftseDataResampled[i]; if (typeof d1 !="undefined") { d = x0 - parseDate(d0.date) > parseDate(d1.date) - x0 ? d1 : d0; update(d); } }

function update(d) { focus.attr("transform", "translate(" + x(parseDate(d.date)) + "," + y(d.close) + ")"); focus.attr("r", 10.5); if (d.change > 0) { theColor = "green"; } else if (d.change < 0) { theColor = "red"; } else { theColor = "black"; } sharePrice.html( '

' + d.date + ': ' + d.close + 'p (' + d.change + '%)

'); }

function mouser(d) { toolTip.transition() .duration(500) .style("opacity", 0); toolTip.transition() .duration(200) .style("opacity", 1); if ((typeof d.size!= "undefined") && (d.size == 3)) { toolTip.attr("class", "tooltip larger"); } else { toolTip.attr("class", "tooltip"); } if (d.change > 0) { theColor = "green"; } else if (d.change < 0) { theColor = "red"; } else { theColor = "black"; } var special = "Close:"; toolTip.html( '

' + d.date + '' + '
' + special + ' ' + d.close + 'p (' + d.change + '%)' + '
' + d.text + '

'); if (width > 568) { xco = d3.mouse(this)[0]; if (xco > (width/2)) { toolTip.style("left", (d3.event.pageX - 230) + "px") .style("top", (d3.event.pageY + 10) + "px"); } else { toolTip.style("left", (d3.event.pageX + 10) + "px") .style("top", (d3.event.pageY + 10) + "px"); }; } else { toolTip.style("left", "20%") .style("bottom", "100px"); } focus.style("display", null); focus.moveToFront(); focus.attr("transform", "translate(" + x(parseDate(d.date)) + "," + y(d.close) + ")") if (typeof d.size!= "undefined") { focus.attr("r", 6.5 + (d.size*pixelRatio)); } else { focus.attr("r", 10.5); } sharePrice.html( '

' + d.date + ': ' + d.close + 'p (' + d.change + '%)

'); }

function zoomed() { if (x.domain()[0] < minDate) { var xx = zoom.translate()[0] - x(minDate) + x.range()[0]; zoom.translate([xx, 0]); } else if (x.domain()[1] > maxDate) { var xx = zoom.translate()[0] - x(maxDate) + x.range()[1]; zoom.translate([xx, 0]); } // resampler ftseDataPerPixel = ftseData.length/width; if (zoom.scale() == 1) { ftseDataResampled = ftseData.filter(function(d, i) { if ((typeof d.text !== "undefined") || (i % Math.ceil(ftseDataPerPixel) == 0)) { return i; } }); } else { ftseDataResampled = ftseData.filter(function(d, i) { if ((parseDate(d.date) > x.domain()[0]) && (parseDate(d.date) < x.domain()[1])) { if (width < 700) { if ((typeof d.text !== "undefined") || (i % Math.ceil(ftseDataPerPixel) == 0)) { return i; } } else { return i; } } }); } focus.style("display", "none"); axes.select(".x.axis").call(xAxis); axes.select(".y.axis").call(yAxis); axes.select(".x.grid") .call(make_x_axis() .tickSize(-height, 0, 0) .tickFormat("")); axes.select(".y.grid") .call(make_y_axis() .tickSize(-width, 0, 0) .tickFormat("")); chartBody.select('.line') .datum(ftseDataResampled) .attr("d", line); ftseGraph.selectAll(".circ") .attr("r", function(d) { if (typeof d.size!= "undefined") { return (d.size*pixelRatio); } else { return 0; } }) .attr("cx", function(d) { return x(parseDate(d.date)); }) .attr("cy", function(d) { return y(d.close); }) } }) } //

There have been some big twists, too. Here are the top six from this year:

8 January

 
Tesco reveals turnaround plans including closure of 43 stores and names Matt Davies as new UK boss. In addition to the 43 stores being closed, 49 planned "very large stores" will not now be opened. 
 

26 January

 
Tesco sells off Blinkbox Music to Australian firm Guvera for an undisclosed sum, but thought to be significantly less than the £10m the supermarket paid to acquire the service. Tesco bought digital service WE7 in 2012, rolling it into its digital entertainment arm, Blinkbox, and rebranding it under the new Blinkbox Music name.
 

10 February

 
Tesco enters growth for the first time in a year after it recorded sales growth of 0.3 per cent to £7.9bn for the 12 weeks to 1 February, according to Kantar Worldpanel.
 

16 February

 
Tesco announces it will cut up to 10,000 jobs  as part of a radical overhaul by chief executive Dave Lewis aimed at halting a slide in profits.
Tesco employs around 314,000 staff. Around 6,000 of those at risk are threatened by the store closures.

17 February

 
Tesco appoints John Allan chairman. Allan began his career in marketing with Lever Brothers and Bristol-Myers, entering the food retail sector for the first time in 1977 when he joined Fine Fare where he was head of marketing, buying and retail operations.
 
In 2009 Allan joined Dixons Retail. Allan said it ?would be fun? to return to retail after a previous decade of experience. He was chairman of Dixons Retail until last year when the electronics retailer merged with the Carphone Warehouse group to form Dixons Carphone.
 

24 March

 
Investors prepare new legal claim over profits misstatement. The shareholders have hired a litigation specialist to seek compensation following a fall in the company's share price, after management revealed the £250m black hole in its profits.

Subscribe

Subscribe to the City A.M. newsletter to have our top stories delivered directly to your inbox.

Subscribe By signing up to our newsletters you agree to the Terms and Conditions and Privacy Policy.