Integrating D3 with Angular-cli - d3.js

I am trying to integrate D3 chart library with Angular CLI. First I installed d3 with npm install d3 --save. Once done my node_modules looks like
d3 version is "d3": "^4.2.2".
Then I set up configuration as below.
angular-cli-build.js
var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
......
'd3/**/*'
]
});
};
system-config.ts
"use strict";
// SystemJS configuration file, see links for more information
// https://github.com/systemjs/systemjs
// https://github.com/systemjs/systemjs/blob/master/docs/config-api.md
/***********************************************************************************************
* User Configuration.
**********************************************************************************************/
/** Map relative paths to URLs. */
const map:any = {
'#angular2-material': 'vendor/#angular2-material',
// 'd3': 'vendor/d3'
'd3': 'vendor/d3/build'
};
/** User packages configuration. */
const materialPackages:string[] = [
'core',
'button',
'icon',
'sidenav',
'toolbar',
'list',
'card'
];
const packages:any = {
'd3': {
format: 'cjs',
defaultExtension: 'js',
main: 'd3'
},
};
materialPackages.forEach(name => {
packages[`#angular2-material/${name}`] = {
format: 'cjs',
defaultExtension: 'js',
main: name
};
});
////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************
* Everything underneath this line is managed by the CLI.
**********************************************************************************************/
const barrels:string[] = [
// Angular specific barrels.
'#angular/core',
'#angular/common',
'#angular/compiler',
'#angular/forms',
'#angular/http',
'#angular/router',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
// Thirdparty barrels.
'rxjs',
// App specific barrels.
'app',
'app/shared',
'app/bar',
'app/chart',
/** #cli-barrel */
];
const cliSystemConfigPackages:any = {};
barrels.forEach((barrelName:string) => {
cliSystemConfigPackages[barrelName] = {main: 'index'};
});
/** Type declaration for ambient System. */
declare var System:any;
// Apply the CLI SystemJS configuration.
System.config({
map: {
'#angular': 'vendor/#angular',
'rxjs': 'vendor/rxjs',
'main': 'main.js',
},
packages: cliSystemConfigPackages
});
// Apply the user's configuration.
System.config({map, packages});
In app.module.ts, I imported d3 as below.
import * as d3 from 'd3';
Then,
#NgModule({
declarations: [AppComponent, d3],
providers: [],
imports: [],
bootstrap: [AppComponent],
})
Following is what my dist folder looks,
When I try to build the project with ng build it gives below error.
Cannot find module 'd3'
Any suggestions are highly appreciated.
Thank You

You should try to add d3 typings to your project, d3 does not include typings and you have to get it to use the import system.
You can :
use the TypeScript Definition Manager in order to import the requested typing in your project :
typings install dt~d3 --global --save
Then you will have the definition file for d3 in your typings directory.
Refers to angular-cli, you can install typings by using npm :
npm install #types/d3 --save-dev
After all, you should take a look to the d3 definition file to be sure that is the correct typing for the latest release of d3.

Related

How to add custom plugin in CKEditor 5 on Laravel Vue 2

How to add a custom plugin, more specifically the Inline widget plugin as mentioned in the example of the documentation of CKEditor in vue CKEditor ?
I have tried to follow the CKEditor setup process using CKEditor from source.
Since Laravel Vue doesn't have vue.config.js i have copied the same code on webpack.mix.js. Initially it failed to complied with an error
Module not found: Error: Can't resolve './#ckeditor/ckeditor5-ui/theme/mixins/_rwd.css' in '
But after removing some of the plugins such as `LinkPlugin, it complies but it run into another error
app.js?id=00c39e33120645d3026e:82180 TypeError: Cannot read properties of null (reading 'getAttribute')
at IconView._updateXMLContent (app.js?id=00c39e33120645d3026e:63098)
at IconView.render (app.js?id=00c39e33120645d3026e:63074)
at IconView.<anonymous> (app.js?id=00c39e33120645d3026e:80777)
at IconView.fire (app.js?id=00c39e33120645d3026e:78186)
at IconView.<computed> [as render] (app.js?id=00c39e33120645d3026e:80781)
at ViewCollection._renderViewIntoCollectionParent (app.js?id=00c39e33120645d3026e:72022)
at ViewCollection.<anonymous> (app.js?id=00c39e33120645d3026e:71883)
at ViewCollection.fire (app.js?id=00c39e33120645d3026e:78186)
at ViewCollection.addMany (app.js?id=00c39e33120645d3026e:74031)
at ViewCollection.add (app.js?id=00c39e33120645d3026e:73996)
Same issue as mentioned here
https://github.com/ckeditor/ckeditor5-vue/issues/24#issuecomment-947333698
But this solution didn't work for me.
Here is my complete webpack.mix.js file
let mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css')
.version();
const path = require('path');
const CKEditorWebpackPlugin = require('#ckeditor/ckeditor5-dev-webpack-plugin');
const {styles} = require('#ckeditor/ckeditor5-dev-utils');
module.exports = {
// The source of CKEditor is encapsulated in ES6 modules. By default, the code
// from the node_modules directory is not transpiled, so you must explicitly tell
// the CLI tools to transpile JavaScript files in all ckeditor5-* modules.
transpileDependencies: [
/ckeditor5-[^/\\]+[/\\]src[/\\].+\.js$/,
],
configureWebpack: {
plugins: [
// CKEditor needs its own plugin to be built using webpack.
new CKEditorWebpackPlugin({
// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
language: 'en',
// Append translations to the file matching the `app` name.
translationsOutputFile: /app/
})
]
},
// Vue CLI would normally use its own loader to load .svg and .css files, however:
// 1. The icons used by CKEditor must be loaded using raw-loader,
// 2. The CSS used by CKEditor must be transpiled using PostCSS to load properly.
chainWebpack: config => {
// (1.) To handle editor icons, get the default rule for *.svg files first:
const svgRule = config.module.rule('svg');
// More rule
const filesRuleIndex = config.module.rules.findIndex(item => {
return item.test.test('.svg')
})
if (filesRuleIndex !== -1) {
config.module.rules[filesRuleIndex].test = /\.(png|jpe?g|gif|webp)$/
const svgRule = {...config.module.rules[filesRuleIndex]}
svgRule.test = /\.svg/
svgRule.exclude = svgRule.exclude || []
svgRule.exclude.push(path.join(__dirname, 'node_modules', '#ckeditor'))
config.module.rules.push(svgRule)
}
config.module.rules.push({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
use: ["raw-loader"]
})
// Then you can either:
//
// * clear all loaders for existing 'svg' rule:
//
// svgRule.uses.clear();
//
// * or exclude ckeditor directory from node_modules:
svgRule.exclude.add(path.join(__dirname, 'node_modules', '#ckeditor'));
// Add an entry for *.svg files belonging to CKEditor. You can either:
//
// * modify the existing 'svg' rule:
//
// svgRule.use( 'raw-loader' ).loader( 'raw-loader' );
//
// * or add a new one:
config.module
.rule('cke-svg')
.test(/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/)
.use('raw-loader')
.loader('raw-loader');
// (2.) Transpile the .css files imported by the editor using PostCSS.
// Make sure only the CSS belonging to ckeditor5-* packages is processed this way.
config.module
.rule('cke-css')
.test(/ckeditor5-[^/\\]+[/\\].+\.css$/)
.use('postcss-loader')
.loader('postcss-loader')
.tap(() => {
return styles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('#ckeditor/ckeditor5-theme-lark'),
},
minify: true
});
});
},
};
Can anyone please tell me what is the proper way of setting this CKEditor to work with custom plugins
And my vue component script is like this
import CKEditor from '#ckeditor/ckeditor5-vue2';
import ClassicEditor from '#ckeditor/ckeditor5-editor-classic/src/classiceditor';
import EssentialsPlugin from '#ckeditor/ckeditor5-essentials/src/essentials';
import BoldPlugin from '#ckeditor/ckeditor5-basic-styles/src/bold';
import ItalicPlugin from '#ckeditor/ckeditor5-basic-styles/src/italic';
//import LinkPlugin from '#ckeditor/ckeditor5-link/src/link';
import ParagraphPlugin from '#ckeditor/ckeditor5-paragraph/src/paragraph';
//Custom Plugin same as in the documentation mentioned above,
//import Placeholder from "../../editor-plugins/Placeholder"; // Commented out
export default {
name: "AddEditDocuments",
props: {},
components:{
ckeditor: CKEditor.component
},
data() {
return {
editor: ClassicEditor,
editorData: '',
editorConfig: {
plugins: [
EssentialsPlugin,
BoldPlugin,
ItalicPlugin,
// LinkPlugin,
ParagraphPlugin
],
toolbar: {
items: [
'bold',
'italic',
'link',
'undo',
'redo'
]
}
},\
}
Packages:
Laravel : 8.76.1
Vue 2
CKEditor 5
Dont use CKEditor5 as it has some bugs in its editor just because of this i was also switch to CKEditor 4. After installing CKeditor using npm use it in the component. No need to configure it globally.
<template>
<ckeditor v-model="obj[name]" :config="editorConfig" ></ckeditor>
</template>
<script>
import CKEditor from 'ckeditor4-vue';
export default {
name: "Ckeditor",
props: {
obj: {
type: Object,
required: true,
},
name: {
type: String,
required: true,
}
},
components: {
ckeditor: CKEditor.component
},
data(){
return {
editorConfig: {
toolbar: [
[
'Bold',
'Italic',
'Link',
'BulletedList',
'NumberedList',
'Undo',
'Redo',
]
],
removePlugins: 'elementspath',
extraPlugins: 'filebrowser,uploadimage',
height: 100,
resize_enabled:false,
}
}
}
}
</script>
<style scoped>
</style>

vuepress local search not showing up [version 2.0.0-beta.22]

I am new to vueppress.
I followed the docs here to create a documentation site. things went well but the search field/input didn't show up. I tried to follow the plugin installation docs here but I got:
I need to install #vuepress/shared-utils
after that I had to install #vue/component-compiler-utils too
but was unable to see the search input. I also tried to add the following to my ./docs/.vuepress/config.ts but still no luck.
plugins: [
[
'#vuepress/plugin-search',
{
searchMaxSuggestions: 10
}
],
]
I don't want to use Algoia search as this is internal documentation.
I had the same issue. Everything was working except the search box was not visible.
The issue was that my ...docs/.vuepress/config.ts was not structured properly. To fix it I followed exactly what the VuePress documentation instructed.
The working config.ts structure
import { defaultTheme } from '#vuepress/theme-default'
import { searchPlugin } from '#vuepress/plugin-search'
module.exports = {
theme: defaultTheme({
...
}),
plugins: [
searchPlugin({
...
})
]
}
Currently I am using VuePress v2.0.0-beta.45
and I used the following to install what I needed:
npm i -D #vuepress/plugin-search#next
npm i -D #vuepress/plugin-register-components#next
Detailed config.ts that is working for me
import { path } from '#vuepress/utils'
import { defaultTheme } from '#vuepress/theme-default'
// Plugins
import { searchPlugin } from '#vuepress/plugin-search'
import { registerComponentsPlugin } from '#vuepress/plugin-register-components'
import navBarItems from './public/navbar'
import sideBar from './public/sidebar'
// SEE: https://v2.vuepress.vuejs.org/reference/default-theme/config.html#config
module.exports = {
// Site Config: https://v2.vuepress.vuejs.org/reference/config.html#site-config
lang: 'en-US',
title: 'Title on Tab and Navbar',
description: '',
// https://v2.vuepress.vuejs.org/reference/default-theme/config.html
theme: defaultTheme({
logo: 'logo-light.png',
logoDark: 'logo-dark.png',
//https://v2.vuepress.vuejs.org/reference/default-theme/config.html#navbar
navbar: navBarItems,
// https://v2.vuepress.vuejs.org/reference/default-theme/config.html#sidebar
sidebar: sideBar
}),
plugins: [
// https://v2.vuepress.vuejs.org/reference/plugin/register-components.html
registerComponentsPlugin({
componentsDir: path.resolve(__dirname, './components')
}),
// https://v2.vuepress.vuejs.org/reference/plugin/search.html#search
searchPlugin({
// getExtraFields: (page) => page.frontmatter.tags,
maxSuggestions: 15,
hotKeys: ['s', '/'],
locales: {
'/': {
placeholder: 'Search',
}
}
})
],
}
Note that I keep my sidebar array and navbar object in different files.
Also I couldn't find any TypeScript reference for the config in VuePress 2x

Unresolved dependencies & Missing global variable name when trying to import #mapbox/mapbox-gl-geocoder

I'm beginning with Svelte and I would like to (more or less) reproduce Mapbox store locator tutorial with Svelte & rollup. (Starting from svelte REPL starter kit).
Everything's fine for loading a map and some markers, but as soon as I try to import this package https://github.com/mapbox/mapbox-gl-geocoder, nothing works anymore and I'm not familiar enough with Svelte to figure out how to setup rollup and fix it.
<script>
import { onMount, setContext } from 'svelte'
import mapbox from 'mapbox-gl/dist/mapbox-gl.js';
import MapboxGeocoder from '#mapbox/mapbox-gl-geocoder'; // <<--- Problem here
mapbox.accessToken = 'xxx';
let map;
let geocoder;
onMount(() => {
map = new mapbox.Map({,,,});
geocoder = new MapboxGeocoder({,,,});
});
</script>
terminal :
bundles src/main.js → public/build/bundle.js...
(!) Missing shims for Node.js built-ins
Creating a browser bundle that depends on 'events'. You might need to include https://github.com/ionic-team/rollup-plugin-node-polyfills
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
events (imported by node_modules/#mapbox/mapbox-gl-geocoder/lib/index.js, events?commonjs-external)
(!) Missing global variable name
Use output.globals to specify browser global variable names corresponding to external modules
events (guessing 'events$1')
created public/build/bundle.js in 2s
browser console :
Uncaught ReferenceError: events$1 is not defined
at main.js:5
Then, I tried to add to my rollup config resolve and polyfills plugins, but have other errors.
rollup.config.js
import svelte from 'rollup-plugin-svelte';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import preprocess from 'svelte-preprocess';
import nodeResolve from '#rollup/plugin-node-resolve';
import nodePolyfills from 'rollup-plugin-node-polyfills';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
nodeResolve(),
nodePolyfills(),
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
preprocess: preprocess()
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
Gives me this
bundles src/main.js → public/build/bundle.js...
LiveReload enabled
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
node_modules/base-64/base64.js
163: }
164:
165: }(this));
^
to conclude: I'm a bit lost :D
thanks in advance

Why 'scaleLinear' never used? and Why I have to included as a <script d3.v4.js>?

$ npm install d3-scale
$ npm install --save-dev rollup rollup-plugin-babel babel-preset-es2015-rollup rollup-plugin-node-resolve
I created the following file.
▼src/scripts/main.js
var yScale = d3.scaleLinear()
.domain([10, 1200])
.range([0, 500]);
console.log(yScale(1200)); // 500
I created the following file.
▼rollup.config.js
import babel from 'rollup-plugin-babel';
import { scaleLinear } from "d3-scale";
export default {
entry: 'src/scripts/main.js',
dest: 'build/js/main.min.js',
format: 'iife',
plugins: [
babel({
exclude: 'node_modules/**',
}),
],
};
$ npm run build
rollup -c
⚠️ 'scaleLinear' is imported from external module 'd3-scale' but
never used
The following file was created automatically
▼build/js/main.min.js
(function () {
'use strict';
var yScale = d3.scaleLinear().domain([10, 1200])
.range([0, 500]);
console.log(yScale(1200)); // 500
}());
I created the following file.
▼index.html
<script src="https://unpkg.com/d3"></script>
<script src="build/js/main.min.js"></script>
Browser access
・console log display 500
・There is no problem.
But when I remove d3v4.js
▼index.html
<script src="build/js/main.min.js"></script>
Browser access
Uncaught ReferenceError: d3 is not defined
Why I have to included as a <script src="https://unpkg.com/d3"></script>?
・Is there a way to avoid loading <script src="https://unpkg.com/d3"></script>?
・Why does not it work properly even if only d3 - scale is read?
2017/4/26
How to include the node-resolve plugin so that Rollup could find the d3-scale source code to include it?
▼rollup.config.js
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
export default {
entry: 'src/scripts/main.js',
dest: 'build/js/main.min.js',
format: 'iife',
plugins: [
babel({
exclude: 'node_modules/**',
}),
resolve({
//I want to know what to write here
})
]
};
You're getting that message because you're importing scaleLinear into your config file, rather than your app. Remove that line from the config file and you won't get the warning.
Strictly speaking, your src/scripts/main.js file should look like this:
import { scaleLinear } from 'd3-scale';
var yScale = scaleLinear() // <-- note there's no `d3.`
.domain([10, 1200])
.range([0, 500]);
console.log(yScale(1200)); // 500
In that case, you may need to tweak your config file, depending on what you want to do:
1. Bundle d3-scale into your app (recommended)
If you wanted to actually include d3-scale and its dependencies in the bundle Rollup creates so that you don't need to load D3 as a separate <script> tag, you would need to include the node-resolve plugin so that Rollup could find the d3-scale source code to include it.
This is what you'll need to do if you don't want to include D3 from unpkg.com.
2. Tell Rollup what d3-scale is
At the moment your app works because window.d3 is assigned to D3. That's totally fine and will work (you wouldn't even need the import declaration at all), but if you wanted to use the more idiomatic ES module approach without bundling d3-scale then you would need to add the following to your config:
import babel from 'rollup-plugin-babel';
export default {
entry: 'src/scripts/main.js',
dest: 'build/js/main.min.js',
format: 'iife',
// tell Rollup that d3-scale is an external package
// and that it corresponds to `window.d3`
external: ['d3-scale'],
globals: {
'd3-scale': 'd3'
},
plugins: [
babel({
exclude: 'node_modules/**',
}),
],
};

How to bundle d3 v4 using webpack

I was using D3 v3 with webpack which was simple with one single package. Now that D3 v4 has become modular with separate packages, I am unable to bundle them into single package.
I have referred to mbostock's article below using rollup but it fails saying it is unable to load d3 from index.js. Can anyone help me with how to bundle them using webpack?
EDIT 1:
I removed d3 from the rollup options and the rollup worked fine. I have explained the steps below
D3 v4 installed.
Added rollup config and storing to ./dist/d3.min.js
pointed webpack to the ./dist/d3.min.js
tried resolve.alias in webpack and require("d3") in one home.js. But no luck it says
cannot resolve module d3 in home.js
tried webpack.Provideplugin in home.js. Still the above error.
Can anyone please help me with getting this d3 loaded?
Rollup.js
import node from "rollup-plugin-node-resolve";
export default {
entry: "index.js",
format: "umd",
moduleName: "d3",
plugins: [node()],
dest: "./dist/d3.js"
};
index.js
export * from "d3-selection";
export * from "d3-zoom";
export * from "d3-scale";
export * from "d3-drag";
export * from "d3-force";
export * from "d3-axis";
webpack.config.js
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: [
//"./dist/d3-combined.js",
"./client/home.js"
,"./client/pages.js"
,"./client/graph.js"
,"./client/orient_databases.js"
,"./node_modules/d3/d3.js",
,"./public/jquery-2.2.4.min.js"
]
,output: {
path: path.join(__dirname,'dist')
// ,path: '/static'
,publicPath: 'http://localhost:3000/scripts/'
,filename: 'bundle.js'
}
,plugins :[
new webpack.ProvidePlugin({
jquery : "jquery"
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
,module: {
// avoid webpack trying to shim process
noParse: /es6-promise\.js$/,
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
// excluding some local linked packages.
// for normal use cases only node_modules is needed.
exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
loader: 'babel-loader',
query : {
presets : ['es2015']
//,optional : ["runtime"]
}
}
]
}
,resolve : {
//root : [path.resolve('./node_modules')],
alias : [ {"d3": path.join(__dirname,"dist/d3.min.js") } ],
modulesDirectories : ["node_modules"]
}
}
There are quite a few incompatibilities with D3 v4's rollup approach and webpack—yours is totally a sensible approach.
It looks like you're missing the minification step? (Rollup.js creates d3.js, but webpack.config.js expects d3.min.js)
It's also possible that webpack v2's new configuration has some relevant fixes.
This setup works for me (using webpack v2):
home.js
let d3 = require('d3');
rollup.config.js
import npm from 'rollup-plugin-node-resolve';
export default {
entry: './d3.bundle.js',
format: 'umd',
moduleName: 'd3',
plugins: [npm({jsnext: true})],
dest: './dist/d3.js'
};
d3.bundle.js
export * from "d3-selection";
export * from "d3-zoom";
export * from "d3-scale";
export * from "d3-drag";
export * from "d3-force";
export * from "d3-axis";
package.json
{
...
"scripts": {
"prepublish": "rollup -c && uglifyjs dist/d3.js -c -m -o dist/d3.min.js"
},
...
}
webpack.config.js
module.exports = {
...
resolve: {
alias: {
'd3': path.resolve(__dirname, 'dist/d3.min.js')
}
},
...
};

Resources