johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Printing gives a black box

I'm using Highcharts in an application. Charts display and work fine in the browser and I can download a bitmap (e.g. a PNG) of a chart. Previously, I used also to be able to print the charts. However, I've just been adding some new charts and noticed that now, when I try to print, I just get a black box where the chart should be. Could anyone suggest how to restore proper printing of the charts?

Application: Rails 6, webpack, Highcharts 8.2.0 (with styledMode=true).

Webpack entry point:

Code: Select all

import Highcharts from 'highcharts';
require('highcharts/modules/debugger')(Highcharts);
require('highcharts/modules/exporting')(Highcharts);
require('highcharts/highcharts-more')(Highcharts);
require('highcharts/modules/solid-gauge')(Highcharts);
require('highcharts/modules/annotations')(Highcharts);
require('highcharts/modules/accessibility')(Highcharts);
window.Highcharts = Highcharts;

Printing attempted in Safari (Version 14.0) and Brave (Version 1.15.75 built on Chromium 86), using macOS 10.14.6.
dominik.c
Posts: 2081
Joined: Fri Aug 07, 2020 7:07 am

Re: Printing gives a black box

Hello johnpettigrew!

We appreciate you reaching out to us!

As far as I understand, everything was working fine, but then you changed something and now you can't print charts, right? What have you changed? Could you provide us your code, so I could investigate it and find the error?

Can't wait for your response! :)
Best regards.
Dominik Chudy
Highcharts Developer
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

Thanks! Whatever change caused this was a while ago, unfortunately, and there's a lot of water gone under the bridge since then! :roll:

Here's a representative piece of code (this would be wrapped in a script block on the webpage but I can't include that here!). Like all my other charts, it just gives a black rectangle when I go to print.

Code: Select all

//<![CDATA[

                document.addEventListener('DOMContentLoaded', function () {var paytopquartile = Highcharts.chart('pay-top-quartile', {
chart:{type:'bar', styledMode: true, className: 'report-proportion-bar', displayErrors: false}, credits:{enabled:false},
accessibility: {description: 'Proportion of women and men in the top pay quartile.'},
title:{text:''},
series:[{name:'Men', data:[65.3]}, {name:'Women', data:[34.7]}],
xAxis:{tickWidth:0, lineColor:'#ffffff', labels:{enabled:false}, title:{enabled:false}},
yAxis:{gridLineColor:'#ffffff', lineColor:'#ffffff', labels:{enabled:false}, max:100, title:{enabled:false}},
exporting:{enabled:false},
plotOptions:{series:{borderRadius:0, pointWidth:60, borderWidth:0, stacking:'percentage', dataLabels:{style:{fontSize:'14px'}, enabled:true, formatter: function() {if(this.series.name) {return this.series.name + ': ' + this.point.y + '%'} else {return this.series.name};}}}},
tooltip:{enabled:false},
legend:{enabled: false},
});});

//]]>
dominik.c
Posts: 2081
Joined: Fri Aug 07, 2020 7:07 am

Re: Printing gives a black box

Hello again!

Sorry for the late response!

I see that you're using styledMode. Probably the styles for styledMode weren't loaded properly. That could be the problem. Remember that you need to import highcharts.css. Check docs and the demo below. They should clarify your issue. :wink:

Docs: https://www.highcharts.com/docs/chart-d ... yle-by-css

Your demo: https://jsfiddle.net/BlackLabel/uobgn4et/

Let me know if that was what you were looking for!
Best regards.
Dominik Chudy
Highcharts Developer
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

Thanks for that suggestion. I had been importing a copy of the css file and thought perhaps it had got out of sync with the version of Highcharts installed via yarn. So, I switched to importing the css directly from '~/node_modules/highcharts' from my app.scss:

Code: Select all

@import "~highcharts/css/highcharts.css";

However, this didn't resolve the issues with black boxes when trying to print.

I then tried importing the css directly from the Highcharts website in my app.scss file, which produces a compilation warning:

Code: Select all

Unable to find uri in '@import https://code.highcharts.com/css/highcharts.css'

And when I load the site despite the compilation warning, it shows black boxes even in the browser. (And, when printing, just a black box as before.)

I've tried disabling all my own Highcharts-targetting css, but it makes no significant difference.

Any ideas?
dominik.c
Posts: 2081
Joined: Fri Aug 07, 2020 7:07 am

Re: Printing gives a black box

Hi again!

That's strange that it doesn't work even in your browser. I need to ask you. Did you import the CSS file in a proper way? Probably it is the mistake that's causing the problem. Could you describe your project settings and provide me your code? :wink:

Best regards!
Dominik Chudy
Highcharts Developer
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

I've double-checked by disabling styledMode in my app, and the charts print fine when I do so (albeit with the wrong styles!), so you're right that the problem's with styledMode.

The styles are imported near the top of my app.scss file like this (with all the other separate scss files):

Code: Select all

@import "5-vendor/highcharts";
This loads an SCSS file from within the application folder, which may admittedly be out of date compared with the actual version of Highcharts I'm running (but see below).

If I force print emulation in my browser, there are no styles at all defined for these elements - all that's in the Inspector is:

Code: Select all

element.style {
}
g[Attributes Style] {
  transform: translate(71, 10) scale(1, 1);
  clip-path: url(#highcharts-afz5t0u-18-);
}
user agent stylesheet :not(svg) {
  transform-origin: 0px 0px;
}
I can therefore make elements be displayed not-black with print emulation enabled if I add my own fill and stroke values to "element.style", which does strongly suggest that I have missing rules in my CSS! I know nothing about the specifics of rendering SVGs with CSS (all my experience to date has been with HTML) but I assume that black is the default "no styles" approach. But I'm not clear why the styles used for screen rendering aren't being used for print rendering, as they would be for HTML.

===

FWIW, I have also tried loading the Highcharts SCSS file directly from node_modules, thusly:

Code: Select all

@import "~highcharts/css/highcharts";
(Note that, in the previous message I loaded the compiled CSS but this should load the SCSS source file.)

I would hope that this would resolve the issue and include all the required styles but, although it compiles with no errors or warnings, only elements that I've explicitly styled in my own CSS are displayed properly, with most lines and points being unstyled. Checking the inspector when building from the source SCSS in node_modules, I can see errors in the compiled scss (even though the build succeeds in webpack). Specifically, the values for the fill and stroke properties are incorrect. For example:

Code: Select all

.highcharts-color-0 {
  fill: "blue" #3086FF;
  stroke: "blue" #3086FF;
}
This doesn't happen when I load the pre-compiled CSS file from node_modules, so there's something odd going on in the build. Also, the specific colours used are different: the same style looks like this in the pre-compiled CSS file:

Code: Select all

.highcharts-color-0 {
  fill: #7cb5ec;
  stroke: #7cb5ec;
}
If I force print emulation in this case, I can see that there are no styles defined for fill and stroke on the SVG elements (as above). So, for some reason, I am just not grabbing the styles for formatting the printed output, even though I *am* grabbing the styles for screen rendering!

Which settings would be useful for me to share? You can see how I'm loading the SCSS here, and how I load the JS in the original post.
dominik.c
Posts: 2081
Joined: Fri Aug 07, 2020 7:07 am

Re: Printing gives a black box

Hi again!

It's an exporting problem. I'm afraid that I can't help you because I don't know how your app is configured. You can try to reproduce this problem in an online editor, so then it could get easier to find a solution.

Best regards!
Dominik Chudy
Highcharts Developer
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

I don't think it is an exporting issue - I can use the "Download as PNG" function without problem (which requires the exporting module, I believe). It's only printing that gives the black box.

The issue is the styles that are (or, indeed aren't) being applied when rendered for print. As I noted above, if I manually add the fill and stroke styles to each element (in the Inspector, having enabled print emulation) then I can make the charts render properly.
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

I realised that there is a publicly accessible version of the app that shows the problem here. (It's a little old, but was clearly set up after the issue arose.) It runs on a free Heroku instance, so takes a few seconds to start up. You'll see that there are various charts on this page that render fine, but all become black boxes when you print or enable print emulation.
dominik.c
Posts: 2081
Joined: Fri Aug 07, 2020 7:07 am

Re: Printing gives a black box

Hi again!

All right, so your CSS is not loaded properly and you're right this is a problem related to styled mode.

It's hard to tell you what's the cause of this problem without knowing how the project structure looks like and in what way you build the project. Do you remember when exactly when this error occurred? You were changing the Highcharts version? From which one to which one? How do you call print? Do you use an export menu to it or something else?

Best regards!
Dominik Chudy
Highcharts Developer
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

I've gone back and reset this repo locally to just after styledMode was enabled, and printing produces the black blocks. Resetting the repo to just before styledMode was enabled, and printing works fine. It's definitely and specifically styledMode that produces the problem.

Certainly, though, I can say this:

  • the problem occurs whether I trigger the Print function manually, use the browser's print emulation (from the console) or trigger print via JS;
  • the problem does not occur when I export the same chart to an image from the export menu.
The project is built with Rails 6 using webpacker (avoiding sprockets and the Rails asset pipeline). Highcharts is installed via yarn. All my JS code is in /app/frontend/packs/app.js and my SCSS code is in /app/frontend/scss/app.scss. The project is built using webpack (as built in to Rails 6) - webpack is a dark art to me (I'm not really a JS developer) and I generally leave it to do its own sweet thing, but here's my webpacker.yml:

Code: Select all

# Note: You must restart bin/webpack-dev-server for changes to take effect

default: &default
  source_path: app/frontend
  source_entry_path: packs
  public_root_path: public
  public_output_path: packs
  cache_path: tmp/cache/webpacker
  check_yarn_integrity: false
  webpack_compile_output: true

  # Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  resolved_paths: []

  # Reload manifest.json on all requests so we reload latest compiled packs
  cache_manifest: false

  # Extract and emit a css file
  extract_css: true

  static_assets_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .tiff
    - .ico
    - .svg
    - .eot
    - .otf
    - .ttf
    - .woff
    - .woff2
    - .csv

  extensions:
    - .mjs
    - .js
    - .sass
    - .scss
    - .css
    - .module.sass
    - .module.scss
    - .module.css
    - .png
    - .svg
    - .gif
    - .jpeg
    - .jpg
    - $
    - jQuery

development:
  <<: *default
  compile: true

  # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
  check_yarn_integrity: true

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: localhost
    port: 3035
    public: localhost:3035
    hmr: false
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    compress: true
    disable_host_check: true
    use_local_ip: false
    quiet: false
    headers:
      'Access-Control-Allow-Origin': '*'
    watch_options:
      ignored: '**/node_modules/**'


test:
  <<: *default
  compile: true

  # Compile test packs to a separate directory
  public_output_path: packs-test

production:
  <<: *default

  # Production depends on precompilation of packs prior to booting for performance.
  compile: true

  # Extract and emit a css file
  extract_css: true

  # Cache manifest.json for performance
  cache_manifest: true
And here's my webpack environment.js

Code: Select all

const { environment } = require('@rails/webpacker');
const TerserPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
const FileManagerPlugin = require("filemanager-webpack-plugin");
const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries");

const webpack = require('webpack');

environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    '$': 'jquery',
    'window.$': 'jquery',
    jQuery: "jquery",
    jquery: "jquery",
    "window.$": "jquery",
    "window.jQuery": "jquery",
    Popper: ["popper.js", "default"]
  })
);

environment.loaders.append('expose', {
  test: require.resolve('jquery'),
  use: [{
    loader: 'expose-loader',
    options: '$'
  }, {
    loader: 'expose-loader',
    options: 'jQuery'
  }]
});

if(process.env.NODE_ENV=='production') {
  const HoneybadgerSourceMapPlugin = require('@honeybadger-io/webpack');
  // See Heroku notes in README https://github.com/honeybadger-io/honeybadger-rails-webpacker-example
  // Assumes Heroku / 12-factor application style ENV variables
  // named HEROKU_SLUG_COMMIT, HONEYBADGER_API_KEY, ASSETS_URL
  const revision = process.env.HEROKU_SLUG_COMMIT || 'MASTER';

  environment.plugins.append(
    'HoneybadgerSourceMap',
    new HoneybadgerSourceMapPlugin({
      apiKey: '5b7c732b',
      assetsUrl: process.env.ASSETS_URL,
      silent: false,
      ignoreErrors: false,
      revision: revision
    })
  );
};

module.exports = environment;
Sorry not to be more helpful!
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

Aha - I think I've found the cause. In the webpacker config file webpacker.yml, I have this setting:

Code: Select all

extract_css: true
Changing this to false leads to the print problem not happening (although it introduces other problems, like the styles not being loaded for a brief period and some very odd layout issues on the charts).

Creating a clean project with just the minimum code to produce a highcharts chart, means it prints OK. But if I set extract_css: true then the problem crops up (black box on print - and, indeed, in the browser too).

It's not a solution to leave this setting as false, because this (as I said) has knock-on problems, most particularly an unwelcome flash of unstyled text on every page change. But does identifying it suggest anything I could do to fix it?
dominik.c
Posts: 2081
Joined: Fri Aug 07, 2020 7:07 am

Re: Printing gives a black box

Hi again!

Congrats on finding the cause! :)

Sure, I understand that it's not good enough and I'll try to find a better solution. Sorry, for the late response, but I need to ask you for some more time, it's not a common problem.

Best regards!
Dominik Chudy
Highcharts Developer
johnpettigrew
Posts: 20
Joined: Fri Jul 26, 2019 2:54 pm

Re: Printing gives a black box

Time is fine. :) Many thanks for helping out - it's much appreciated!

The perils of the modern world, though. Things like webpack are great, right up to the point where they do something unexpected! :roll:

Return to “Highcharts Usage”