Tesco: The decline and fall of the supermarket giant and its share price in one chart

The business world is reacting to the news that Tesco has racked up a £6.38bn loss – one of the biggest losses ever made by a UK company.
The beleaguered supermarket’s pre-tax losses for the year are even higher than the £5bn markets had been expecting.
There was also a big hit from the writedown of its property portfolio.
Here, in one interactive chart, is the path leading to these car-crash results. Hover over any of the bubbles on the visualisation to reveal information about that particular twist or turn in Tesco’s fortunes.

"); } else { jQuery(".chartPaint").html("
To make it easier for mobile users, we've broken the chart up into two time periods.

July - December 2014
January 2015 - April 2015
");
}
d3.selection.prototype.moveToFront = function() { return this.each(function(){ this.parentNode.appendChild(this); }); };
d3.selection.prototype.moveToBack = function() { return this.each(function() { var firstChild = this.parentNode.firstChild; if (firstChild) { this.parentNode.insertBefore(this, firstChild); } }); };
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: