HighCharts in R Shiny App - highcharts

I am using highcharts in a shiny app. When I have the following, everything works.
fluidRow( tags$head(tags$script(src = "https://code.highcharts.com/highcharts.js"),
tags$script(src = "https://code.highcharts.com/highcharts-more.js"),
tags$script(src = "https://code.highcharts.com/modules/exporting.js"),
tags$script(src = "https://code.highcharts.com/modules/heatmap.js"),
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }")
However my goal is to not go through the highcharts website and access the highcharts folder locally. I placed the highcharts folder in the root directory and did the following.
fluidRow( tags$head(tags$script(src = "/HighCharts/js/highcharts.js"),
tags$script(src = "/HighCharts/js/highcharts-more.js"),
tags$script(src = "/HighCharts/js/modules/exporting.js"),
tags$script(src = "/HighCharts/js/modules/heatmap.js"),
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }")
I am getting nothing but errors. Any help is appreciated.

You need to put your files in a www folder in the root of your shiny app.
so based on your path of /HighCharts/js/modules/ you would have a folder structure of:
root/
+-www/
+-HighCharts/
+-js/
- hightcharts.js
- highcharts-more.js
+-modules/
- exporting.js
- heatmap.js

Related

google-map-react not loading- Uncaught TypeError: Cannot read properties of undefined (reading 'getChildren')

import React from "react";
import GoogleMapReact from "google-map-react";
const AnyReactComponent = ({ text }) => <div>{text}</div>;
export default function AppMapPage() {
const defaultProps = {
center: {
lat: 10.99835602,
lng: 77.01502627,
},
zoom: 11,
};
return (
<div style={{ height: "100vh", width: "100%" }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "my key" }}
defaultCenter={defaultProps.center}
defaultZoom={defaultProps.zoom}
>
<AnyReactComponent lat={59.955413} lng={30.337844} text="My Marker" />
</GoogleMapReact>
</div>
);
}
I have been trying to solve it for a while. I am trying to run simple example of google-map-react. But, This does not load maps. Instead gives following errors and the page is blank.
google_map_markers.js:100 Uncaught TypeError: Cannot read properties of undefined (reading 'getChildren')
at o._getState (google_map_markers.js:100:1)
at new o (google_map_markers.js:248:1)
at constructClassInstance (react-dom.development.js:13522:1)
at updateClassComponent (react-dom.development.js:20497:1)
at beginWork (react-dom.development.js:22440:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)
at invokeGuardedCallback (react-dom.development.js:4274:1)
at beginWork$1 (react-dom.development.js:27405:1)
at performUnitOfWork (react-dom.development.js:26513:1)
To resolve these issues, you have to remove *<React.StrictMode>* in the index.js file.
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>);
To
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
it's due to versioning. I downgraded from 18 to 17 and it worked. Man sometimes open source code consumes your all day.
I Just removed the <React.StrictMode> in the index.js file and it worked for me.

Ionic 4: The "src" content of an "img" tag is not updating when I change it from the controller in IOS

I am developing an app for Android and IOS.
I have a profile page where the user can change profile pictures. The photo appears in the view and is changed in real time.
My code is like this in the view:
<img alt="logo" style="width:15vh; height:15vh; border-radius: 50%;" src="{{pictureusuariomenu}}">
pictureusuariomenu is a variable found in the controller.
With that variable what I do is, it is the URL of the image that I upload, I update it there. here is the function:
updateStoredImages(name) {
this.storage.get(STORAGE_KEY).then(images => {
let arr = JSON.parse(images);
if (!arr) {
let newImages = [name];
this.storage.set(STORAGE_KEY, JSON.stringify(newImages));
} else {
arr.push(name);
this.storage.set(STORAGE_KEY, JSON.stringify(arr));
}
let filePath = this.file.dataDirectory + name;
let resPath = this.pathForImage(filePath);
// alert(resPath);
this.urlImage=resPath;
let newEntry = {
name: name,
path: resPath,
filePath: filePath
};
this.images=[]; //borrar las imagenes anteriores (no crear la lista de imagenes)
this.images = [newEntry, ...this.images];
this.urlImage = this.images[0].path;
this.colocarImagenEnProfile(this.urlImage);
this.ref.detectChanges(); // trigger change detection cycle
});
}
In this line:
this.colocarImagenEnProfile(this.urlImage);
What I do is:
colocarImagenEnProfile(newFileName){
this.pictureusuariomenu=newFileName;
}
Now in android is working fine this way of updating the profile image in view:
Before:
After:
But in IOS this isn't working. The view is not updated at all
Before:
After:
Nothing appears, just a few letters. But the view doesn't update in IOS.
What could it be?
My specifications:
you forgot to bind it. put it instead of your HTML tag:
<img alt="logo" style="width:15vh; height:15vh; border-radius: 50%;" [src]="pictureusuariomenu">
I don't know why but you have to bind it that way.
also, you have to use window.Ionic.WebView.convertFileSrc(); function, if using angular you need to sanitize it. like this:
this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))

Rails 6 + Webpacker 4 + PostCSS & #font-face + Local fonts

I'm trying to import fonts in my rails 6 app for hours now.
It's a fresh app using Rails 6, Webpacker 4 and PostCSS.
Everything is loaded (with no error) through webpack (css, js, images). Compilation is correct. Image are properly displayed (using css background:url).
OTF/EOT/WOFF fonts : Compiled properly and fonts inside my #font-face are loaded and salted by Webpack. The font are not rendered properly in view (I got the default browser font instead).
I think I tried everything I know. I Switched file-loader for url-loader and back, with no success. Changed the folders hierachy, tried different fonts files, absolute urls (resolve-url-loader). Nothing seems to work.
Anyone would be kind enough point me to the right direction or to share a working config of local fonts loading with webpacker on rails 6 and PostCSS ?
Thank you in advance for your help.
Here is my config :
javascript > fonts
raleway_thin-webfont.woff
javascript > packs > application.js
require.context('../fonts/', true, /\.(eot|ttf|woff|woff2|otf)$/i);
import "./application.pcss";
import "js";
require("#rails/ujs").start();
require("turbolinks").start();
require("#rails/activestorage").start();
require("channels");
javascript > packs > application.pcss
#font-face {
font-family: 'Raleway';
src: url('../fonts/raleway_thin-webfont.eot'), format('eot');
}
#font-face {
font-family: 'Amaranth';
src: url('../fonts/Amaranth-Regular.otf'), format('otf');
}
#test-div { font-family: 'Raleway'; }
/postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
})
]
};
/config > webpack > environment.js
const webpack = require("webpack");
const { environment } = require("#rails/webpacker");
const { VueLoaderPlugin } = require("vue-loader");
const vue = require("./loaders/vue");
// const url = require('./loaders/url');
environment.plugins.append(
"Provide",
new webpack.ProvidePlugin({
jQuery: "jquery",
$: "jquery",
Tether: "tether",
tether: "tether",
Popper: ["popper.js", "default"]
})
);
["css", "moduleCss"].forEach(loaderName => {
const loader = environment.loaders.get(loaderName);
loader.test = /\.(p?css)$/i;
environment.loaders.insert(loaderName, loader);
});
environment.plugins.prepend("VueLoaderPlugin", new VueLoaderPlugin());
environment.loaders.prepend("vue", vue);
// environment.loaders.prepend("url", url);
// avoid using both file and url loaders
// environment.loaders.get("file").test = /\.(tiff|ico|svg)$/i;
module.exports = environment;
/config > webpack > loaders > url (not in use)
module.exports = {
test: [/\.eot$/, /\.otf$/, /\.ttf$/, /\.woff$/, /\.woff2$/],
use: [
{
loader: "url-loader",
options: {
limit: 10000,
name: "[name]-[hash].[ext]"
}
}
]
};

Rails Webpacker SCRIPT5009: 'app' is undefined - IE11 issues

For some reason most of my JS work in IE11 and lower fails. No issues with Chrome, Firefox, and Edge.
I have in the application.html.slim file:
meta http-equiv='X-UA-Compatible" content="IE=edge'
I found this: github webpacker thread
So I went through and tried the following in my config > webpack > production.js:
if (environment.plugins.getIndex('UglifyJs') !== -1) {
const plugin = environment.plugins.get('UglifyJs');
plugin.options.uglifyOptions.ecma = 5;
}
environment.config.optimization.minimizer[0].options.uglifyOptions.ecma = undefined
environment.plugins.get("UglifyJs").options.uglifyOptions.ecma = 5
None of those worked. In the console I'm getting:
SCRIPT5009: 'app' is undefined
From my home page I have it set up:
= content_for :head do
= stylesheet_pack_tag 'styles/home'
= javascript_pack_tag 'home'
= javascript_include_tag "//maps.googleapis.com/maps/api/js?key=#{ENV['MAP_KEY']}"
= content_for :body do
.container
.row
#map-banner.banner[type"hidden" data-location=all_locations.to_json]
=render template: '/layouts/application'
javascript:
document.addEventListener('DOMContentLoaded', app.home);
Then in my javascript > packs > home.js
import { mapStyle } from './styles/mapStyle';
app.home = () => {
function init() {
setupSlider();
homeSlider();
startGoogleMap();
let tabs = document.querySelectorAll('a.tab');
for (let tab of tabs) {
tab.addEventListener('click', tabClicked);
}
document
.querySelector('#region-select_')
.addEventListener('change', selectClicked);
}
return init();
};
Current versions:
webpack 3.12.0
rails 5.2.2
yarn 1.17.3
bootstrap 4.3.1
When I checked in the Network on my tiny-slider.js it's returning a status code of 304 however its returning 200 in Chrome. Any idea why it's not compiling?
Leaving this here in case someone finds it useful. Updated config > webpack > environment.js with:
environment.loaders.get('babel').exclude = [];

How to create multiple output paths in Webpack config

Does anyone know how to create multiple output paths in a webpack.config.js file? I'm using bootstrap-sass which comes with a few different font files, etc. For webpack to process these i've included file-loader which is working correctly, however the files it outputs are being saved to the output path i specified for the rest of my files:
output: {
path: __dirname + "/js",
filename: "scripts.min.js"
}
I'd like to achieve something where I can maybe look at the extension types for whatever webpack is outputting and for things ending in .woff .eot, etc, have them diverted to a different output path. Is this possible?
I did a little googling and came across this *issue on github where a couple of solutions are offered, edit:
but it looks as if you need to know the entry point in able to specify an output using the hash method
eg:
var entryPointsPathPrefix = './src/javascripts/pages';
var WebpackConfig = {
entry : {
a: entryPointsPathPrefix + '/a.jsx',
b: entryPointsPathPrefix + '/b.jsx',
c: entryPointsPathPrefix + '/c.jsx',
d: entryPointsPathPrefix + '/d.jsx'
},
// send to distribution
output: {
path: './dist/js',
filename: '[name].js'
}
}
*https://github.com/webpack/webpack/issues/1189
however in my case, as far as the font files are concerned, the input process is kind of abstracted away and all i know is the output. in the case of my other files undergoing transformations, there's a known point where i'm requiring them in to be then handled by my loaders. if there was a way of finding out where this step was happening, i could then use the hash method to customize output paths, but i don't know where these files are being required in.
Webpack does support multiple output paths.
Set the output paths as the entry key. And use the name as output template.
webpack config:
entry: {
'module/a/index': 'module/a/index.js',
'module/b/index': 'module/b/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
generated:
└── module
├── a
│   └── index.js
└── b
└── index.js
I'm not sure if we have the same problem since webpack only support one output per configuration as of Jun 2016. I guess you already seen the issue on Github.
But I separate the output path by using the multi-compiler. (i.e. separating the configuration object of webpack.config.js).
var config = {
// TODO: Add common Configuration
module: {},
};
var fooConfig = Object.assign({}, config, {
name: "a",
entry: "./a/app",
output: {
path: "./a",
filename: "bundle.js"
},
});
var barConfig = Object.assign({}, config,{
name: "b",
entry: "./b/app",
output: {
path: "./b",
filename: "bundle.js"
},
});
// Return Array of Configurations
module.exports = [
fooConfig, barConfig,
];
If you have common configuration among them, you could use the extend library or Object.assign in ES6 or {...} spread operator in ES7.
You can now (as of Webpack v5.0.0) specify a unique output path for each entry using the new "descriptor" syntax (https://webpack.js.org/configuration/entry-context/#entry-descriptor) –
module.exports = {
entry: {
home: { import: './home.js', filename: 'unique/path/1/[name][ext]' },
about: { import: './about.js', filename: 'unique/path/2/[name][ext]' }
}
};
If you can live with multiple output paths having the same level of depth and folder structure there is a way to do this in webpack 2 (have yet to test with webpack 1.x)
Basically you don't follow the doc rules and you provide a path for the filename.
module.exports = {
entry: {
foo: 'foo.js',
bar: 'bar.js'
},
output: {
path: path.join(__dirname, 'components'),
filename: '[name]/dist/[name].bundle.js', // Hacky way to force webpack to have multiple output folders vs multiple files per one path
}
};
That will take this folder structure
/-
foo.js
bar.js
And turn it into
/-
foo.js
bar.js
components/foo/dist/foo.js
components/bar/dist/bar.js
Please don't use any workaround because it will impact build performance.
Webpack File Manager Plugin
Easy to install copy this tag on top of the webpack.config.js
const FileManagerPlugin = require('filemanager-webpack-plugin');
Install
npm install filemanager-webpack-plugin --save-dev
Add the plugin
module.exports = {
plugins: [
new FileManagerPlugin({
onEnd: {
copy: [
{source: 'www', destination: './vinod test 1/'},
{source: 'www', destination: './vinod testing 2/'},
{source: 'www', destination: './vinod testing 3/'},
],
},
}),
],
};
Screenshot
If it's not obvious after all the answers you can also output to a completely different directories (for example a directory outside your standard dist folder). You can do that by using your root as a path (because you only have one path) and by moving the full "directory part" of your path to the entry option (because you can have multiple entries):
entry: {
'dist/main': './src/index.js',
'docs/main': './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, './'),
}
This config results in the ./dist/main.js and ./docs/main.js being created.
In my case I had this scenario
const config = {
entry: {
moduleA: './modules/moduleA/index.js',
moduleB: './modules/moduleB/index.js',
moduleC: './modules/moduleB/v1/index.js',
moduleC: './modules/moduleB/v2/index.js',
},
}
And I solve it like this (webpack4)
const config = {
entry: {
moduleA: './modules/moduleA/index.js',
moduleB: './modules/moduleB/index.js',
'moduleC/v1/moduleC': './modules/moduleB/v1/index.js',
'moduleC/v2/MoculeC': './modules/moduleB/v2/index.js',
},
}
You definitely can return array of configurations from your webpack.config file. But it's not an optimal solution if you just want a copy of artifacts to be in the folder of your project's documentation, since it makes webpack build your code twice doubling the overall time to build.
In this case I'd recommend to use the FileManagerWebpackPlugin plugin instead:
const FileManagerPlugin = require('filemanager-webpack-plugin');
// ...
plugins: [
// ...
new FileManagerPlugin({
onEnd: {
copy: [{
source: './dist/*.*',
destination: './public/',
}],
},
}),
],
You can only have one output path.
from the docs https://github.com/webpack/docs/wiki/configuration#output
Options affecting the output of the compilation. output options tell Webpack how to write the compiled files to disk. Note, that while there can be multiple entry points, only one output configuration is specified.
If you use any hashing ([hash] or [chunkhash]) make sure to have a consistent ordering of modules. Use the OccurenceOrderPlugin or recordsPath.
I wrote a plugin that can hopefully do what you want, you can specify known or unknown entry points (using glob) and specify exact outputs or dynamically generate them using the entry file path and name. https://www.npmjs.com/package/webpack-entry-plus
I actually wound up just going into index.js in the file-loader module and changing where the contents were emitted to. This is probably not the optimal solution, but until there's some other way, this is fine since I know exactly what's being handled by this loader, which is just fonts.
//index.js
var loaderUtils = require("loader-utils");
module.exports = function(content) {
this.cacheable && this.cacheable();
if(!this.emitFile) throw new Error("emitFile is required from module system");
var query = loaderUtils.parseQuery(this.query);
var url = loaderUtils.interpolateName(this, query.name || "[hash].[ext]", {
context: query.context || this.options.context,
content: content,
regExp: query.regExp
});
this.emitFile("fonts/"+ url, content);//changed path to emit contents to "fonts" folder rather than project root
return "module.exports = __webpack_public_path__ + " + JSON.stringify( url) + ";";
}
module.exports.raw = true;
u can do lik
var config = {
// TODO: Add common Configuration
module: {},
};
var x= Object.assign({}, config, {
name: "x",
entry: "./public/x/js/x.js",
output: {
path: __dirname+"/public/x/jsbuild",
filename: "xbundle.js"
},
});
var y= Object.assign({}, config, {
name: "y",
entry: "./public/y/js/FBRscript.js",
output: {
path: __dirname+"/public/fbr/jsbuild",
filename: "ybundle.js"
},
});
let list=[x,y];
for(item of list){
module.exports =item;
}
The problem is already in the language:
entry (which is a object (key/value) and is used to define the inputs*)
output (which is a object (key/value) and is used to define outputs*)
The idea to differentiate the output based on limited placeholder like '[name]' defines limitations.
I like the core functionality of webpack, but the usage requires a rewrite with abstract definitions which are based on logic and simplicity... the hardest thing in software-development... logic and simplicity.
All this could be solved by just providing a list of input/output definitions... A LIST INPUT/OUTPUT DEFINITIONS.
Vinod Kumar's good workaround is:
module.exports = {
plugins: [
new FileManagerPlugin({
events: {
onEnd: {
copy: [
{source: 'www', destination: './vinod test 1/'},
{source: 'www', destination: './vinod testing 2/'},
{source: 'www', destination: './vinod testing 3/'},
],
},
}
}),
],
};

Resources