将 c3.js 折线图导出为 png 图像不起作用
Exporting c3.js line charts to png images does not work
我正在使用 SVG.toDataURL() 将 c3js 图表导出为 png 图像。将图表导出为 png 可以正常工作。
对于折线图,它们无法正确呈现。例如
- 增加了x轴和y轴的宽度。
- 线条不正确,而不是线条显示深黑色区域。
下面是导出png的代码
function exportImageAsPNG(){
var svgElements = $("#chart").find('svg');
var svg ;
svgElements.each(function() {
svg = this;
});
var img = document.getElementById("fromcanvas");
svg.toDataURL("image/png", {
callback: function(data) {
img.setAttribute("src", data)
}
})
}
当我使用 canvag 库时,同样的事情发生了。
var $container = $('#chart'),
content = $container.html().trim(),
canvas = document.getElementById('svg-canvas');
// Draw svg on canvas
canvg(canvas, content);
// Change img be SVG representation
var theImage = canvas.toDataURL('image/png');
$("#hiddenPng").attr('href', theImage);
$("#hiddenPng span").trigger("click");
问题是导出器函数在执行导出时仅考虑内联 CSS 样式。换句话说,出口商正在失去对 C3 的 css 设置的跟踪,因此你的图表在出口之前看起来就像这个家伙的权利
https://github.com/c3js/c3/issues/356
最重要的是,黑色三角形是由某些特定 .c3
元素的 fill
属性 引起的。 c3.css
默认将这些设置为 none
,但您的出口商不知道。
参见:
并且,如果您从 c3.min.css
...
手动关闭 fill
属性
您需要以某种方式将这些特定元素的 fill
CSS 属性 设置为内联 CSS(如 ),然后再导出
这里有一个快速的 plainJS 修复方法,如图所示在 genChart();
和 exportImageAsPNG();
之间添加这些行以解决您的问题。
genChart();
var nodeList = document.getElementById('chart').querySelector('svg').querySelectorAll('.c3-chart path');
var nodeList2 = document.getElementById('chart').querySelector('svg').querySelectorAll('.c3-axis path');
var nodeList3 = document.getElementById('chart').querySelector('svg').querySelectorAll('.c3 line');
var line_graph = Array.from(nodeList);
var x_and_y = Array.from(nodeList2).concat(Array.from(nodeList3));
line_graph.forEach(function(element){
element.style.fill = "none";
})
x_and_y.forEach(function(element){
element.style.fill = "none";
element.style.stroke = "black";
})
exportImageAsPNG();
JSFiddle:
https://jsfiddle.net/vtange/vajs3cmf/
可能有点晚了,但我希望这个解决方案对未来的开发者有所帮助:
- 上面经过验证的解决方案不适用于 Barchart 和其他人
- 所以,基于同样的原则,我做了以下工作,使导出适用于每种图表类型。这里有一些例子:
假设我们在 html 中有这个,并且图表已经用 c3:
生成
<div id="chartID" class="chart-content"></div>
然后,在我们的 JS 中,这是导出函数:
function exportChartToPng(chartID){
//fix weird back fill
d3.select('#'+chartID).selectAll("path").attr("fill", "none");
//fix no axes
d3.select('#'+chartID).selectAll("path.domain").attr("stroke", "black");
//fix no tick
d3.select('#'+chartID).selectAll(".tick line").attr("stroke", "black");
var svgElement = $('#'+chartID).find('svg')[0];
saveSvgAsPng(svgElement, chartID+'.png');
}
注意:saveSvgAsPng 工具来自 https://github.com/exupero/saveSvgAsPng
对于一直遇到这个问题的人,我得到的这个也许可以帮助你...
var nodeList = $('svg .c3-chart path.c3-shape.c3-shape.c3-line');
var fillArea = Array.from(nodeList);
fillArea.forEach(function(element){
element.style.fill = "none";
})
我正在使用 SVG.toDataURL() 将 c3js 图表导出为 png 图像。将图表导出为 png 可以正常工作。
对于折线图,它们无法正确呈现。例如
- 增加了x轴和y轴的宽度。
- 线条不正确,而不是线条显示深黑色区域。
下面是导出png的代码
function exportImageAsPNG(){
var svgElements = $("#chart").find('svg');
var svg ;
svgElements.each(function() {
svg = this;
});
var img = document.getElementById("fromcanvas");
svg.toDataURL("image/png", {
callback: function(data) {
img.setAttribute("src", data)
}
})
}
当我使用 canvag 库时,同样的事情发生了。
var $container = $('#chart'),
content = $container.html().trim(),
canvas = document.getElementById('svg-canvas');
// Draw svg on canvas
canvg(canvas, content);
// Change img be SVG representation
var theImage = canvas.toDataURL('image/png');
$("#hiddenPng").attr('href', theImage);
$("#hiddenPng span").trigger("click");
问题是导出器函数在执行导出时仅考虑内联 CSS 样式。换句话说,出口商正在失去对 C3 的 css 设置的跟踪,因此你的图表在出口之前看起来就像这个家伙的权利
https://github.com/c3js/c3/issues/356
最重要的是,黑色三角形是由某些特定 .c3
元素的 fill
属性 引起的。 c3.css
默认将这些设置为 none
,但您的出口商不知道。
参见:
并且,如果您从 c3.min.css
...
fill
属性
您需要以某种方式将这些特定元素的 fill
CSS 属性 设置为内联 CSS(如 ),然后再导出
这里有一个快速的 plainJS 修复方法,如图所示在 genChart();
和 exportImageAsPNG();
之间添加这些行以解决您的问题。
genChart();
var nodeList = document.getElementById('chart').querySelector('svg').querySelectorAll('.c3-chart path');
var nodeList2 = document.getElementById('chart').querySelector('svg').querySelectorAll('.c3-axis path');
var nodeList3 = document.getElementById('chart').querySelector('svg').querySelectorAll('.c3 line');
var line_graph = Array.from(nodeList);
var x_and_y = Array.from(nodeList2).concat(Array.from(nodeList3));
line_graph.forEach(function(element){
element.style.fill = "none";
})
x_and_y.forEach(function(element){
element.style.fill = "none";
element.style.stroke = "black";
})
exportImageAsPNG();
JSFiddle: https://jsfiddle.net/vtange/vajs3cmf/
可能有点晚了,但我希望这个解决方案对未来的开发者有所帮助:
- 上面经过验证的解决方案不适用于 Barchart 和其他人
- 所以,基于同样的原则,我做了以下工作,使导出适用于每种图表类型。这里有一些例子:
假设我们在 html 中有这个,并且图表已经用 c3:
生成<div id="chartID" class="chart-content"></div>
然后,在我们的 JS 中,这是导出函数:
function exportChartToPng(chartID){
//fix weird back fill
d3.select('#'+chartID).selectAll("path").attr("fill", "none");
//fix no axes
d3.select('#'+chartID).selectAll("path.domain").attr("stroke", "black");
//fix no tick
d3.select('#'+chartID).selectAll(".tick line").attr("stroke", "black");
var svgElement = $('#'+chartID).find('svg')[0];
saveSvgAsPng(svgElement, chartID+'.png');
}
注意:saveSvgAsPng 工具来自 https://github.com/exupero/saveSvgAsPng
对于一直遇到这个问题的人,我得到的这个也许可以帮助你...
var nodeList = $('svg .c3-chart path.c3-shape.c3-shape.c3-line');
var fillArea = Array.from(nodeList);
fillArea.forEach(function(element){
element.style.fill = "none";
})