Can't get full screen buttons to work with highcharts-vue - vue.js

I'm using the highcharts-vue wrapper within my vue project. Things are going smooth except for the fact that I can't get the viewFullscreen option to work.
I've set things up following the docs and included the following within my main.js
import exportingInit from 'highcharts/modules/exporting'`
exportingInit(Highcharts);
The export function is working within my charts. For every chart I've set up the options as follow:
exporting: {
buttons: {
contextButton: {
menuItems: ['viewFullScreen', 'downloadPNG', 'downloadJPEG', 'downloadPDF']
}
}
}
alle the buttons ar visible and working except for the viewFullscreen button. that one isn't showing.
Following the docs from the highcharts api there isn't anything mentioned about having to include extra options or so to make use of the vieFullscreen mode.
Any thoughts on this?

You need to change the first string from viewFullScreen to viewFullscreen:
exporting: {
buttons: {
contextButton: {
menuItems: ['viewFullscreen', 'downloadPNG', 'downloadJPEG', 'downloadPDF']
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/ekr2mw7f/
API Reference: https://api.highcharts.com/highcharts/exporting.buttons.contextButton.menuItems

Related

Docusaurus: How can I have multiple versions of different docs in the docs directory?

I'm working with Docusaurus to create a documentation site for 3 different education courses - all within the docs folder.
So I'm looking for a way to have the version be different across folders in there, or figure out what the best strategy for this is.
Right now, in my docusaurus.config.js I have:
module.exports = {
presets: [
'#docusaurus/preset-classic',
docs: {
lastVersion: 'current',
versions: {
current: {
label: '1.0.0',
path: '1.0.0',
},
},
},
],
};
But I'm not sure how to keep track of 3 different versions across 3 different docs all within the same site.
Swizzle the navbar via wrapping
yarn run swizzle #docusaurus/theme-classic NavbarItem/DocsVersionDropdownNavbarItem -- --wrap
Modify the swizzled component like so:
src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js:
import React from "react";
import DocsVersionDropdownNavbarItem from '#theme-original/NavbarItem/DocsVersionDropdownNavbarItem';
import { useLocation } from '#docusaurus/router';
export default function DocsVersionDropdownNavbarItemWrapper(props) {
const { docsPluginId, className, type } = props
const { pathname } = useLocation()
/* (Custom) check if docsPluginId contains pathname
Given that the docsPluginId is 'charge-controller' and the routeBasePath is 'charge-controller', we can check against the current URI (pathname).
If the pathname contains the docsPluginId, we want to show the version dropdown. Otherwise, we don't want to show it.
This gives us one, global, context-aware version dropdown that works with multi-instance setups.
You want to declare a version dropdown for each plugin in your navbarItems config property for this to work well.
const doesPathnameContainDocsPluginId = pathname.includes(docsPluginId)
if (!doesPathnameContainDocsPluginId) {
return null
}
return <DocsVersionDropdownNavbarItem {...props} />;
}
For this to work, you need to have your documentation (based on products) split up using multi-instances: (https://docusaurus.io/docs/docs-multi-instance#docs-navbar-items)
Note that the preset docsPlugin ID always is "default".
You can try to use
import {
useActivePluginAndVersion,
} from '#docusaurus/plugin-content-docs/client';
const version = activePluginAndVersion.activeVersion.name; // use label instead of name if issues arise.
instead to get the current docsPluginId, name or label.
This would be the more "robust" solution I think. That said, we do use the solution I provided above as-is and it works fine for now.

How to fix navbar overlap on dropdown items with a vuepress site

There's always an overlap with Navbar dropdown when more than one is clicked. It focuses and takes a few minutes to clear this becomes a problem because it causes clutter.
The configuration for this in the Vuepress docs is just to add navbar items and ariaLabel any know how I can stop this behaviour.
themeConfig: {
nav: [
{
text: 'Languages',
ariaLabel: 'Language Menu',
items: [
{ text: 'Chinese', link: '/language/chinese/' },
{ text: 'Japanese', link: '/language/japanese/' }
]
}
]
}
Here's an example
To answer your question one would need to address two distinct issues:
how do I run custom JavaSCript in VuePress?
how do I close any previously open dropdowns on click in my current VuePress theme, using JavaScript?
For the first problem there are several solutions (one of them being by using a custom component with code run in its mounted() hook, but this would require you to include that component in every page and make sure it doesn't run more than one time (since you want to bind events to elements).
I believe the cleanest way would be by adding a <script> to <head> which can be achieved by adding this to the head prop of your .vuepress/config.js export:
head: [
// ...existing stuff, if any,
['script', {}, `
(function() {
// your code here...
})();
`]
]
However, there are a few problems with the above solution. Firstly, it's going to be run as soon as it's parsed, and that's inside the <head> tag. Which means none of the contents of your page are rendered yet. And the second problem is you're in a template literal. You don't really want to be writing JavaScript code in a template literal. Ideally you should be able to put your code in a '.js' file and append it as a <script> tag.
In order to do that, you need to create a .vuepress/public/ folder, if you don't already have one. Place your .js file in there (I used test.js but feel free to name it as you like). Modify the above code to:
['script', {}, `
(function() {
var s = document.createElement('script');
s.src = './test.js';
var h = document.querySelector('head');
h.appendChild(s);
})();
`]
Change ./test.js to your file's name.
Now your file has clean JavaScript and the door is open. Your code executes in the window object context.
To answer the second part of your question, well..., it largely depends on the theme you are using. If you're using the default theme (which seems to be the case, from the SS you posted), this should work, if placed inside your .js file:
document.addEventListener('DOMContentLoaded', fixDropDowns);
function fixDropDowns() {
document.body.addEventListener('click', (ev) => {
const header = document.querySelector('header');
if (header) {
const dds = header.querySelectorAll('.dropdown-wrapper');
[...dds].forEach(el => el.classList.remove('open'));
const curr = ev.target.closest('.dropdown-wrapper');
if (curr) {
curr.classList.add('open');
}
}
})
}
But it's based on a close inspection of the generated markup.
Specifically on the fact the dropdowns have a class of .dropdown-wrapper and that they're opened by toggling class open on them. The above is just an example and will likely not work on other themes and might even stop working on the default theme in some future version.

highstock. Don't update navigator series visibility

i'm having some troubles solving this.
I need to keep navigator series always visible.
The problem is when i click in one legend item, the serie linked to this legend dissappears. Thats fine.
But the serie in the navigator dissappears to, and i don't want this.
I tried with the "adaptToUpdatedData" parameter, not working.
I tried handling the events in "legendItemClick" and hide show the series manually, but this hides the navigator series also.
Please help! I tried almost everything.
The only i managed to achieve it is keeping all the series with the parameter "showInNavigator" false, and then add the series in navigator.series.
But i think is not a good solution.
Thanks.
I add hide events to series with showInNavigator: true. These call a function which does:
var chart = this.$refs.highcharts.chart
for (var series of chart.navigator.series) {
series.setVisible(true, false)
}
chart.redraw()
You can use Highcharts removeEvent method to remove the connection when changing visibility between the chart series and the navigator series:
chart: {
events: {
load() {
this.series.forEach(function(s) {
if (!s.baseSeries) {
H.removeEvent(s, 'show');
H.removeEvent(s, 'hide');
}
});
}
}
},
Live demo: http://jsfiddle.net/BlackLabel/69rwjsce/
API Reference: https://api.highcharts.com/class-reference/Highcharts#.removeEvent%3CT%3E

Displaying Custom Images in 'tools' config options of ext.grid.panel

I am only a month old with extjs and still experimenting. My question is: I have a grid panel and within it the 'tools' config options. I am using this to enable/disable a Ext.grid.feature.Grouping variable. The 2 handler functions have the logic to disable/enable the 2 views by clicking on the 2 'cross' buttons that appear on the right side of the header. The logic is fine. However, I would like to display my set of custom images in place of the 'cross' buttons. Can this be done? If yes, how? Do I need to make some changes in the css code for that?
I have looked into the documentation and also done a good search but nothing seems to answer my question.
Specify a custom type config on your tools:
Ext.create('Ext.grid.Panel', {
...
tools: [
{
type: 'enable-grouping',
handler: function() {
...
}
},
{
type: 'disable-grouping',
handler: function() {
...
}
}
]
});
Then define the following classes in a stylesheet to style your new tools:
.x-tool-enable-grouping {
background-image: url('path/to/tool/image/enable-grouping.png');
}
.x-tool-disable-grouping {
background-image: url('path/to/tool/image/disable-grouping.png');
}
The size of a tool image should be 15 x 15 px

Dynamically adding html to panel

I am designing an app in sencha touch2. I have a panel object in my JS file. I need to dynamically set the text/html for this component. The store for this component is defined at the application level. Following is the thing I worked out:
Ext.define('class_name',{
....
config : {
pnlObj : null,
...
}
initialize : function() {
this.config.pnlObj = Ext.create('Ext.Panel');
var store = Ext.data.Storemanager.lookup('some_store');
store.on('load',this.loadStore,this);
this.setItems([{
//some items here
{
flex : 2,
// id : 'somepnl',
config : this.config.pnlObj
}
}]);
},
loadStore : function(store, rec) {
var text = rec.get('text');
var panel = this.config.pnlObj;
// var panel = Ext.getCmp('somepanl');
panel.setHtml(text);
}
});
When I inspect the inspect the element using Firebug console, I can find the panel added there. But I am not able to set the html dynamically. no html text is set there. I tried adding it using panel.add() & panel.setItems() method which doesn't work. If I give an id to that panel(somepanel here) and try to access it using Ext.getCmp('smpanel') then in that case it works fine. I have found that using Ext.getCmp() is not a good practice and want to avoid it as it might somewhere break my code in the future.
I guess the way I am instantiating the panel object is creating some issue. Can someone suggest the best way of doing it?
The recommended way to manipulate your components in Sencha Touch 2 is using controller, through refs and control configs. For example, your panel has a config like this: xtype:'myPanel', then in your controller:
refs: {
myPanel: 'myPanel'
}
control:{
myPanel: {
on_an_event: 'set_html_for_my_panel'
}
}
Lastly, define your function:
set_html_for_my_panel: function()
{
this.getMyPanel().setHtml('my_updated_html');
}
P/S: Behind the scene, Sencha Touch 2 uses Ext.ComponentQuery for refs in controllers