SVG to PDF conversion is successful with Plotly.js, however, C3.js is currently experiencing issues with this

After an onclick event, I am using css2pdf to save my svg chart to pdf. It functions perfectly with plotly.js, but unfortunately not with c3.js - you can check out my fiddle here: http://jsfiddle.net/3hs7cs4f/

I suspect the issue lies within the c3.js svg properties, yet I am unsure how to resolve it.

Below is the code snippet:

<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css" rel="stylesheet" />
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="http://www.cloudformatter.com/Resources/Pages/CSS2Pdf/Scrip /xeponline.jqplugin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
</head>

<body>
<br><br>
  <!-- Source and on-click event for plotly.js -->
  <div id="plotly_chart" style="width: 90%; height: 270px"></div>
  <button onclick="return xepOnline.Formatter.Format('plotly_chart',{pageWidth:'11in', pageHeight:'8.5in',render:'download', srctype:'svg'});">Get plotly_PDF</button>

  <!-- Source and on-click event for c3.js-->
  <div id="c3_chart" style="width: 90%; height: 270px"></div>
  <button onclick="return xepOnline.Formatter.Format('c3_chart',{pageWidth:'11in', pageHeight:'8.5in',render:'download', srctype:'svg'});">Get c3_PDF</button>

<!-- JAVASCRIPT for plotly.js chart -->
<script type="text/javascript">
  Chart = document.getElementById('plotly_chart');

 Plotly.plot( Chart, [{
   x: [1, 2, 3, 4, 5],
   y: [1, 2, 4, 8, 16] }], { 
   margin: { t: 0 } } );
</script>

<!-- JAVASCRIPT for j3.js chart -->
<script type="text/javascript">
   var chart = c3.generate({
   bindto: '#c3_chart',
   padding: {
       top: 10,
       right: 70,
       bottom: 50,
       left: 75,
   },
   data: {
       columns: [
           ['data1', 100, 200, 150, 300, 200],
           ['data2', 400, 500, 250, 700, 300],
       ]
   }});
</script>

My attempts to save c3.js charts in various methods have been unsuccessful. The only solution that has worked for me is the ng-c3 exporter from annatomka, utilizing the AngularJS module (https://github.com/annatomka/ng-c3-export). However, this method does not provide full control over css settings, and the downloaded png quality is limited by screen resolution. Therefore, I am keen on finding a pdf exporter, specifically css2pdf which seems to handle all css settings. Any suggestions or alternative methods to save c3 chart as pdf are greatly appreciated. Thank you for your assistance!

Answer №1

Upon further investigation, it appears that the SVG generated by c3 does not include the necessary SVG namespace for Css2PDF compatibility.

You can refer to the first FAQ on for more information about this common issue.

To address this issue temporarily, a simple hack has been implemented to add the required namespace attribute to the plot before printing. Although there may be better solutions available, this workaround ensures that your output is displayed correctly.

<script>
   function addnsandprint(){
     $('#c3_chart').find('svg').attr('xmlns','http://www.w3.org/2000/svg');
     xepOnline.Formatter.Format('c3_chart',{pageWidth:'11in', 
        pageHeight:'8.5in',render:'download', srctype:'svg'});
   }
</script>

You can view the demonstration on this Fiddle: http://jsfiddle.net/3hs7cs4f/9/

Final Result:

https://i.sstatic.net/oTxlY.png

Please note that if your SVG utilizes xlink, you should also include the "xmlns:xlink" attribute with the value "http://www.w3.org/1999/xlink" in your code for proper formatting.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The button's URL will vary depending on the condition

As a newcomer to coding, I am seeking guidance on creating a button with dynamic URLs based on user input. For instance, let's say the button is labeled "Book Now" and offers two package options: Standard and Premium. I envision that if a user selec ...

Is there a way to display a secondary header once the page is scrolled down 60 pixels?

.nav-header2{ background: purple; display: flex; justify-content: center; align-items: center; } .header2-container{ width: 68vw; height: 60px; padding: 0 2vh; border: 1px solid red; ...

Is it possible to verify the existence of several arrays of data in a MongoDB database using Node.js?

I'm trying to verify if certain data exists in a database. If the data does exist, I want to set the value of k to 1. global.k = 0 let roll = {roll0:"1616",roll1:"234"} for (let i = 0; i < inputcount; i++) { let obj1 = roll["roll" + i]; const ...

What advantages does utilizing NPM provide compared to directly incorporating the JavaScript library into an MVC project?

When working on an MVC project, I experimented with two different methods of including jQuery: I first downloaded the jQuery files and manually added them to the project, as shown here: https://i.sstatic.net/2TjqX.png I also tried using the bundle sett ...

Halting a function upon meeting a specific condition and resuming it based on another condition

There is a checkbox that acts like a switch button to toggle a functionality ON/OFF. When it is turned ON, the function should work, and when it is turned OFF, the function should not work. However, the issue arises when the switch is turned ON, the fun ...

Is there a way to enable multiple selections in a particular section?

Currently, I am in the process of working on my step by step order and I want to express my gratitude for all the assistance I have received so far. Despite the help, I still have some unanswered questions! The steps in my project are categorized into dif ...

The Angular ternary operator can be used in conjunction with functions for optimal

Consider this scenario: I have two functions that are triggered by a button click: <button ng-click="functionOne || functionTwo()"></button> However, I want to optimize this setup so that the functions are only called if they return a value. ...

Unexpected failure in retrieving data with Javascript Fetch

I'm attempting to create a login form that retrieves data from another website, but I keep encountering an error that says Error: Failed to Fetch Upon inspecting the code, I can't seem to identify any issues, but it's possible that the prob ...

"Exploring the world of Mean.js with Node.js background functionalities

Struggling with my mean.js app as I try to figure out how to implement background processes. I want these processes to run continuously, interacting with the mongodb database and handling tasks like cleanup, email notifications, and tweets. I need access ...

The issue of not being able to add data to the client is encountered in a local setup involving Socket.io, MSSQL

I have a large dataset that needs to be retrieved from a SQL server using Node.js and then broadcasted to clients in real-time using Socket.IO. I've been successful in fetching the data, but the UI on the client side isn't updating. Although I c ...

The specified method is not recognized as a function in the ReactJS library

Within my reactJS application, there is a function that calls upon a helper function to retrieve the result of a calculation. The component looks like this: import React, { Component } from "react"; import * as d3 from "d3"; class DrawImage extends Comp ...

Techniques for Utilizing MongoDB Aggregation to Extract Specific Fields from Results

Welcome, everyone! I'm diving into the world of MongoDB aggregation, and after running some queries, I've finally obtained the following result: "result" : [ { "_id" : "531d84734031c76f06b853f0" }, { "_id" : "5316739 ...

Unable to modify page property status through the Notion API

I've been attempting to use the Notion JS-sdk to update a page's status using their API. However, I've run into some issues that I can't seem to resolve. Updating the status requires modifying the properties object, but no matter what ...

Issues with Jquery Cycle not functioning as expected

I've been delving into the world of Jquery, attempting to create a basic SlideShow, but unfortunately, the desired effect isn't happening... Here's the layout of my HTML file: <!doctype html> <html lang="en"> <head> ...

Enhancing event listener using AngularJS and Jasmine: spying on callback functions

Can someone assist me with spyOnning a method connected to an event using scope.$on in a factory service, using Jasmine? The actual method is being called instead of the spy. Here is a plinkr I created showcasing the issue: http://plnkr.co/edit/2RPwrw?p=pr ...

What is the best way to modify specific data retrieved from an API using Angular?

After successfully listing some data from an API using ngFor, I am facing an issue with editing the data. Whenever I click the edit button, it edits the entire data instead of just the specific row. Below is the code snippet for reference: HTML <table ...

Trigger an AJAX request by clicking a button using PHP

I've seen this question asked multiple times, but none of the answers seem to relate to my specific situation. I have a button that when clicked, should call a JavaScript function, passing it a PHP variable. The AJAX will then send that variable to a ...

Unable to locate template or render function for Vue Draggable Next component

Looking to incorporate Vue Draggable Next into a Vue 3 example page but encountering some challenges. I've attempted to follow the instructions in the repository. However, I ran into issues when importing the Vue Draggable Next component and had to re ...

In the ASP.NET framework, users can download an Excel file using Response.End, accompanied by a JavaScript loader on the client side. While I have successfully implemented the loader, I

Is there a different approach to displaying or hiding a loader when using Response.write and Response.end, as the client script does not function properly after response.end()? ...

Troubleshooting a Vue 2 component's prop receiving an incorrect value

I'm currently working on creating a menu that navigates between categories. When a category has a sub-category, it should return a boolean value indicating whether it has a sub-category or not. <template> <select><slot></slot ...