DEV Community

loading...

Help needed with D3 and autocompletion.

Martin Gillis
Just new to programming, making a leap towards learning and applying some cool technologies.
・1 min read

Hello everyone!

Wondering if someone has any advice on my D3 environment configuration? I'm having some issues using an external javascript file (I'm using MacVim with the YouCompleteMe plugin). The following script tag approach does work for me (no autocompletion though).

(index.html)

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <title>Page Title</title>

    <script type="text/javascript"
            src="js/packages/node_modules/d3/dist/d3.js">
    </script>

  </head>
  <body>
    <script type="text/javascript">
      var dataset = [5, 10, 15, 20, 25];
      d3.select("body").selectAll("p")
        .data(dataset)
        .enter()
        .append("p")
        .text("Enter some code!");
    </script>
  </body>
</html>

However, I would like to use an external javascript file so I can have autocompletion.

If I try the following as (referencing my js file):

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <title>Page Title</title>

    <script type="text/javascript"
            src="js/packages/node_modules/d3/dist/d3.js">
    </script>

  </head>
  <body>
    <script type="text/javascript"src="js/main.js"></script>
  </body>
</html>

(main.js)

import * as d3 from 'd3'

var dataset = [5, 10, 15, 20, 25]

d3.select('body').selectAll('p')
  .data(dataset)
  .enter()
  .append('p')
  .text('Enter some code!')

I have autocompletion when editing the js file using the approach, but when I try to view the html file, I am getting the following error:

"Unexpected token '*'. import call expects exactly one argument."

Even if I put the d3.js file in js/d3.js, I am still getting the same error. Perhaps I am just missing something trivial here, any help would be appreciated.

Thanks!

-Martin

Discussion (6)

Collapse
hmgillis profile image
Martin Gillis Author

Thanks @jamestthompson3 for the pointer! Setting the ominfunc to 'javascriptcomplete#CompleteJS' in my html filetype file did provide access to the javascript autocompletion, no d3 functions.

What does work is having the 'import * as d3 from 'location of d3.js file' in my case it was 'import * from '../d3/d3.js'' in the main.js.

I ended up creating vim autocommands to comment out the import statement on save and uncomment when I enter insert mode. Yes, a bit of a hack... I will put the code below if anyone is interested. You can put in your vimrc or a javascript.vim file located in a /.vim/after/ftplugin/ directory. That way changes are only added to the filetype that vim has already set. I think this is a little safer? Anyways, code is below. Hope it helps someone else.

augroup d3_javascript
    autocmd!
    autocmd InsertEnter <buffer> :1 :s /^\/\/ import \* as d3 from\>/import \* as d3 from/e
    autocmd BufWrite <buffer> :1 :s /^import \* as d3 from\>/\/\/ import \* as d3 from/e | ''
augroup END

The 'e' at the end ignores errors if already commented out and the ( | ''), two single quotes, will return your cursor back to your previous line after execution.

Collapse
jamestthompson3 profile image
jamestthompson3

Are you bundling your javascript before serving it, or is all the code in the main.js file? It seems that YCM is using tsserver for javascript completion which would explain why you need the import statement to get it to work. If you are bundling, then you don't need to import D3 in your HTML file, and YCM should give correct completion without having to comment and uncomment your import statement every time you edit / save the file.

Collapse
hmgillis profile image
Martin Gillis Author

Pretty new at this. No, not doing any bundling. I work on my main.js file which is referenced in my index.html.

I've been reading a bit on bundling though. I do have nodejs and npm installed on my machine now. Just reading on where to go from here. I see that I need to do a 'npm init' to get my package.json initialized...from there I am still reading.

Thread Thread
jamestthompson3 profile image
jamestthompson3

If you’re not bundling, I would recommend using completion based on your path. For more info about setting the path in vim, I recommend this article.

Thread Thread
hmgillis profile image
Martin Gillis Author

Thank you!

Collapse
jamestthompson3 profile image
jamestthompson3

Most likely YCM is setting the completion based on the file type. You should be able to check what omnicomplete function is set by :set omnifunc