чтобы загрузить диаграмму как изображение,
сначала создайте изображение из <svg>
,
диаграммы, затем нарисуйте изображение на элементе <canvas>
,
, затем вы можете использовать canvas.toDataURL
дляполучить строку base64 изображения для скачивания.
см. Функцию buildImageUrl
в следующем рабочем фрагменте.
нажмите кнопку Загрузка , чтобы увидеть ее в действии.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
.hidden {
display: none;
visibility: hidden;
}
</style>
</head>
<body>
<div>
<input type="button" id="download" value="Download">
</div>
<div>
<canvas class="hidden" id="canvas"></canvas>
</div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%d-%b-%y").parse;
// Set the ranges
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(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// Adds the svg canvas
var svg = d3.select("body")
.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 + ")");
// Load the data
var data = [
{date: '1-May-12', close: 58.13},
{date: '30-Apr-12', close: 53.98},
{date: '27-Apr-12', close: 67.00},
{date: '26-Apr-12', close: 89.70},
{date: '25-Apr-12', close: 99.00},
{date: '24-Apr-12', close: 130.28},
{date: '23-Apr-12', close: 166.70},
{date: '20-Apr-12', close: 234.98},
{date: '19-Apr-12', close: 345.44},
{date: '18-Apr-12', close: 443.34},
{date: '17-Apr-12', close: 543.70},
{date: '16-Apr-12', close: 580.13},
{date: '13-Apr-12', close: 605.23},
{date: '12-Apr-12', close: 622.77},
{date: '11-Apr-12', close: 626.20},
{date: '10-Apr-12', close: 628.44},
{date: '9-Apr-12', close: 636.23},
{date: '5-Apr-12', close: 633.68},
{date: '4-Apr-12', close: 624.31},
{date: '3-Apr-12', close: 629.32},
{date: '2-Apr-12', close: 618.63},
{date: '30-Mar-12', close: 599.55},
{date: '29-Mar-12', close: 609.86},
{date: '28-Mar-12', close: 617.62},
{date: '27-Mar-12', close: 614.48},
{date: '26-Mar-12', close: 606.98}
];
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the valueline path.
svg.append("path")
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("d", valueline(data));
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("fill", "none")
.attr("stroke", "grey")
.attr("stroke-width", 1)
.attr("shape-rendering", "crispEdges")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("fill", "none")
.attr("stroke", "grey")
.attr("stroke-width", 1)
.attr("shape-rendering", "crispEdges")
.call(yAxis);
// Change font
d3.selectAll("text")
.attr("fill","#444")
.style("font-family","Verdana")
.attr("stroke","none");
// Add download button event listener
document.getElementById('download').addEventListener('click', buildImageUrl);
/**
* build image
*/
function buildImageUrl() {
var canvas; // canvas element
var domUrl; // object url
var image; // chart image
var imageUrl; // chart image url
var svg; // svg element
// add svg namespace to chart
svg = document.getElementsByTagName('svg')[0];
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
// create image url from svg
domUrl = window.URL || window.webkitURL || window;
imageUrl = domUrl.createObjectURL(new Blob([svg.outerHTML], {type: 'image/svg+xml'}));
// create chart image
image = new Image();
image.onload = function() {
// add image to canvas
canvas = document.getElementById('canvas');
canvas.setAttribute('width', parseFloat(svg.getAttribute('width')));
canvas.setAttribute('height', parseFloat(svg.getAttribute('height')));
canvas.getContext('2d').drawImage(image, 0, 0);
// download image
downloadImage(canvas.toDataURL('image/png'));
domUrl.revokeObjectURL(imageUrl);
}
image.src = imageUrl;
}
/**
* download image of chart
*/
function downloadImage(imageUrl) {
var browserIsIE; // determine if browser is IE
var downloadLink; // anchor dom element to trigger download
var fileName; // donwload file name
// determine browser, download the image
fileName = 'chart.png';
browserIsIE = false || !!document.documentMode;
if (browserIsIE) {
// convert image uri to blob, use ie navigator to download
window.navigator.msSaveBlob(base64ToBlob(imageUrl.substr(imageUrl.indexOf(',') + 1), 'data:image/png'), fileName);
} else {
// create anchor dom element to image uri, raise click event
downloadLink = document.createElement('a');
downloadLink.href = imageUrl;
downloadLink.download = fileName;
raiseEvent(downloadLink, 'click');
}
}
/**
* create and execute an event object
*/
function raiseEvent(element, eventType) {
var eventRaised; // event object
// determine how and create the event
if (document.createEvent) {
eventRaised = document.createEvent('MouseEvents');
eventRaised.initEvent(eventType, true, false);
element.dispatchEvent(eventRaised);
} else if (document.createEventObject) {
eventRaised = document.createEventObject();
element.fireEvent('on' + eventType, eventRaised);
}
}
</script>
</body>