Skip to content

Instantly share code, notes, and snippets.

@cyrilmesvayn
Last active January 24, 2018 02:07
Show Gist options
  • Save cyrilmesvayn/981767e80ee6fa23fc5611697426ef8c to your computer and use it in GitHub Desktop.
Save cyrilmesvayn/981767e80ee6fa23fc5611697426ef8c to your computer and use it in GitHub Desktop.
Chrome : Using chartist and exporting them to PNG
.chart .ct-grid {
stroke: rgba(0, 0, 0, .1);
stroke-dasharray: 1px;
}
.chart .ct-label {
fill: #545454;
color: #545454;
font-size: 0.9em;
}
.chart .chartist-tooltip {
background-color: rgba(51, 51, 51, 0.9);
color: rgba(255,255,255,0.9);
}
.chart .chartist-tooltip:before {
border-top-color: rgba(51, 51, 51, 0.9);
}
.chart .chartist-tooltip-meta {
font-weight: 700;
}
.chart .chartist-tooltip-value {
font-weight: 400;
font-variant: italic;
}
.chart .ct-point {
stroke-width: 8px;
}
.chart .ct-area {
fill-opacity: 0.6;
}
.chart svg {
background: #e9edf4;
}
.chart .ct-series-a .ct-slice-donut, .chart .ct-series-a .ct-line, .chart .ct-series-a .ct-point, .chart .ct-series-a .ct-bar {
stroke : #00cc01;
}
.chart .ct-series-a .ct-area {
fill: #00cc01;
}
.chart .ct-series-b .ct-slice-donut, .chart .ct-series-b .ct-line, .chart .ct-series-b .ct-point, .chart .ct-series-b .ct-bar {
stroke : #ff177a;
}
.chart .ct-series-b .ct-area {
fill: #ff177a;
}
.chart .ct-series-c .ct-slice-donut, .chart .ct-series-c .ct-line, .chart .ct-series-c .ct-point, .chart .ct-series-c .ct-bar {
stroke : #30d1ff;
}
.chart .ct-series-c .ct-area {
fill: #30d1ff;
}
.chart .ct-series-d .ct-slice-donut, .chart .ct-series-d .ct-line, .chart .ct-series-d .ct-point, .chart .ct-series-d .ct-bar {
stroke : #ffdd42;
}
.chart .ct-series-d .ct-area {
fill: #ffdd42;
}
.chart .ct-series-e .ct-slice-donut, .chart .ct-series-e .ct-line, .chart .ct-series-e .ct-point, .chart .ct-series-e .ct-bar {
stroke : #00b801;
}
.chart .ct-series-e .ct-area {
fill: #00b801;
}
.chart .ct-series-f .ct-slice-donut, .chart .ct-series-f .ct-line, .chart .ct-series-f .ct-point, .chart .ct-series-f .ct-bar {
stroke : #e6156e;
}
.chart .ct-series-f .ct-area {
fill: #e6156e;
}
.chart .ct-series-g .ct-slice-donut, .chart .ct-series-g .ct-line, .chart .ct-series-g .ct-point, .chart .ct-series-g .ct-bar {
stroke : #2bbce6;
}
.chart .ct-series-g .ct-area {
fill: #2bbce6;
}
.chart .ct-series-h .ct-slice-donut, .chart .ct-series-h .ct-line, .chart .ct-series-h .ct-point, .chart .ct-series-h .ct-bar {
stroke : #e6c73b;
}
.chart .ct-series-h .ct-area {
fill: #e6c73b;
}
.chart .ct-series-i .ct-slice-donut, .chart .ct-series-i .ct-line, .chart .ct-series-i .ct-point, .chart .ct-series-i .ct-bar {
stroke : #00a301;
}
.chart .ct-series-i .ct-area {
fill: #00a301;
}
.chart .ct-series-j .ct-slice-donut, .chart .ct-series-j .ct-line, .chart .ct-series-j .ct-point, .chart .ct-series-j .ct-bar {
stroke : #cc1262;
}
.chart .ct-series-j .ct-area {
fill: #cc1262;
}
.chart .ct-series-k .ct-slice-donut, .chart .ct-series-k .ct-line, .chart .ct-series-k .ct-point, .chart .ct-series-k .ct-bar {
stroke : #26a7cc;
}
.chart .ct-series-k .ct-area {
fill: #26a7cc;
}
.chart .ct-series-l .ct-slice-donut, .chart .ct-series-l .ct-line, .chart .ct-series-l .ct-point, .chart .ct-series-l .ct-bar {
stroke : #ccb135;
}
.chart .ct-series-l .ct-area {
fill: #ccb135;
}
.chart .ct-series-m .ct-slice-donut, .chart .ct-series-m .ct-line, .chart .ct-series-m .ct-point, .chart .ct-series-m .ct-bar {
stroke : #008f01;
}
.chart .ct-series-m .ct-area {
fill: #008f01;
}
.chart .ct-series-n .ct-slice-donut, .chart .ct-series-n .ct-line, .chart .ct-series-n .ct-point, .chart .ct-series-n .ct-bar {
stroke : #b21055;
}
.chart .ct-series-n .ct-area {
fill: #b21055;
}
.chart .ct-series-o .ct-slice-donut, .chart .ct-series-o .ct-line, .chart .ct-series-o .ct-point, .chart .ct-series-o .ct-bar {
stroke : #2292b2;
}
.chart .ct-series-o .ct-area {
fill: #2292b2;
}
.chart .ct-series-p .ct-slice-donut, .chart .ct-series-p .ct-line, .chart .ct-series-p .ct-point, .chart .ct-series-p .ct-bar {
stroke : #b29b2e;
}
.chart .ct-series-p .ct-area {
fill: #b29b2e;
}
.chart .ct-series-q .ct-slice-donut, .chart .ct-series-q .ct-line, .chart .ct-series-q .ct-point, .chart .ct-series-q .ct-bar {
stroke : #007a01;
}
.chart .ct-series-q .ct-area {
fill: #007a01;
}
.chart .ct-series-r .ct-slice-donut, .chart .ct-series-r .ct-line, .chart .ct-series-r .ct-point, .chart .ct-series-r .ct-bar {
stroke : #990e49;
}
.chart .ct-series-r .ct-area {
fill: #990e49;
}
.chart .ct-series-s .ct-slice-donut, .chart .ct-series-s .ct-line, .chart .ct-series-s .ct-point, .chart .ct-series-s .ct-bar {
stroke : #1d7d99;
}
.chart .ct-series-s .ct-area {
fill: #1d7d99;
}
.chart .ct-series-t .ct-slice-donut, .chart .ct-series-t .ct-line, .chart .ct-series-t .ct-point, .chart .ct-series-t .ct-bar {
stroke : #998528;
}
.chart .ct-series-t .ct-area {
fill: #998528;
}
/* Alt for donuts*/
.chart .ct-series-a .ct-slice-donut {
stroke : #00cc01;
}
.chart .ct-series-b .ct-slice-donut {
stroke : #00b801;
}
.chart .ct-series-c .ct-slice-donut {
stroke : #00a301;
}
.chart .ct-series-d .ct-slice-donut {
stroke : #008f01;
}
.chart .ct-series-e .ct-slice-donut {
stroke : #007a01;
}
.chart .ct-series-f .ct-slice-donut {
stroke : #ff177a;
}
.chart .ct-series-g .ct-slice-donut {
stroke : #e6156e;
}
.chart .ct-series-h .ct-slice-donut {
stroke : #cc1262;
}
.chart .ct-series-i .ct-slice-donut {
stroke : #b21055;
}
.chart .ct-series-j .ct-slice-donut {
stroke : #990e49;
}
.chart .ct-series-k .ct-slice-donut {
stroke : #30d1ff;
}
.chart .ct-series-l .ct-slice-donut {
stroke : #2bbce6;
}
.chart .ct-series-m .ct-slice-donut {
stroke : #26a7cc;
}
.chart .ct-series-n .ct-slice-donut {
stroke : #2292b2;
}
.chart .ct-series-o .ct-slice-donut {
stroke : #1d7d99;
}
.chart .ct-series-p .ct-slice-donut {
stroke : #ffdd42;
}
.chart .ct-series-q .ct-slice-donut {
stroke : #e6c73b;
}
.chart .ct-series-r .ct-slice-donut {
stroke : #ccb135;
}
.chart .ct-series-s .ct-slice-donut {
stroke : #b29b2e;
}
.chart .ct-series-t .ct-slice-donut {
stroke : #998528;
}
<div class="chart">
<div id="chartist-plot" class="ct-chart ct-golden-section"></div>
<br>
<button type="button" id="rasterCanvas">Raster to Canvas</button>
</div>
<canvas id="canvas"></canvas>
//Ref : https://gionkunz.github.io/chartist-js/examples.html#example-timeseries-moment
var chart = new Chartist.Line('#chartist-plot', {
series: [
{
name: 'series-1',
data: [
{x: new Date(143134652), y: 53},
{x: new Date(143234652), y: 40},
{x: new Date(143340052), y: 45},
{x: new Date(143366652), y: 40},
{x: new Date(143410652), y: 20},
{x: new Date(143508652), y: 32},
{x: new Date(143569652), y: 18},
{x: new Date(143579652), y: 11}
]
},
{
name: 'series-2',
data: [
{x: new Date(143134652), y: 53},
{x: new Date(143234652), y: 35},
{x: new Date(143334652), y: 30},
{x: new Date(143384652), y: 30},
{x: new Date(143579652), y: 11}
]
}
]
}, {
axisX: {
type: Chartist.FixedScaleAxis,
divisor: 5,
labelInterpolationFnc: function(value) {
return moment.unix(value).format('MMM D');
}
},
axisY: {
labelInterpolationFnc: function(value) {
return value;
}
},
low: 0
});
//Refs :
//https://gionkunz.github.io/chartist-js/api-documentation.html#chartistbase-function-on
//https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas
//https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
//https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
chart.on('created', function(data) {
inlineCSStoSVG(chart.container.id);
});
document.getElementById("rasterCanvas").addEventListener('click', function() {
exportToCanvas(chart.container.id);
});
//NB: not exhaustive, but it'll do for our usecase.
function inlineCSStoSVG(id) {
var nodes = document.querySelectorAll("#" + id + " *");
for (var i = 0; i < nodes.length; ++i) {
var elemCSS = window.getComputedStyle(nodes[i], null);
nodes[i].removeAttribute('xmlns');
nodes[i].style.fill = elemCSS.fill;
nodes[i].style.fillOpacity = elemCSS.fillOpacity;
nodes[i].style.stroke = elemCSS.stroke;
nodes[i].style.strokeLinecap = elemCSS.strokeLinecap;
nodes[i].style.strokeDasharray = elemCSS.strokeDasharray;
nodes[i].style.strokeWidth = elemCSS.strokeWidth;
nodes[i].style.fontSize = elemCSS.fontSize;
nodes[i].style.fontFamily = elemCSS.fontFamily;
//Solution to embbed HTML in foreignObject https://stackoverflow.com/a/37124551
if (nodes[i].nodeName === "SPAN") {
nodes[i].setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
}
}
}
function exportToCanvas(id) {
var svgElem = document.querySelector("#" + id + " svg");
svgElem.setAttribute("xmlns", "http://www.w3.org/2000/svg");
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.canvas.height = svgElem.clientHeight;
ctx.canvas.width = svgElem.clientWidth;
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
img.crossOrigin = "Anonymous";
var blob = undefined;
//catch is not working, but I leave it here as a clue to help with blob in MSIE, if you need it to start something up
//IEsupport : As per https://gist.github.com/Prinzhorn/5a9d7db4e4fb9372b2e6#gistcomment-2075344
//foreignObject is not supported at all in IE as per https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject
try {
blob = new Blob([svgElem.outerHTML], {
type: "image/svg+xml;charset=utf-8"
});
}
catch (e) {
if (e.name == "InvalidStateError") {
var bb = new MSBlobBuilder();
bb.append(svgElem.outerHTML);
blob = bb.getBlob("image/svg+xml;charset=utf-8");
}
else {
throw e; //Fallthrough exception, if it wasn't for IE corner-case
}
}
var url = DOMURL.createObjectURL(blob);
img.onload = function() {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment