larshei
Cannot figure out why my Vega plot and JS Hook do not work
I was trying to add timeline graphs to my current application.
The application uses Surface UI 0.6.1 and LiveView 0.16.x.
Throughout the application I made use of JS Hooks every now and then, e.g. to draw or update markers on a Leaflet Map and all worked very well so far.
Now I am running into 2 problems:
- I cannot figure out how to add vega lite to my phoenix project. I followed the Third-party JS packages
section from GitHub - phoenixframework/esbuild: An installer for esbuild · GitHub, as in runningnpm installin the assets directory. However, I cannot see any files being added anywhere, but the compiler is also not complaining onimport vegaEmbed from 'vega-embed'. Where are the packages located?
- It seems like my Hooks do not work, but I do not see a difference to the Hooks I used before. Here is the code, the
console.logstatement is not showing in the console output in Chrome (always using “empty cache and hard reload” when reloading the page):
JS
import vegaEmbed from 'vega-embed'
const XyDiagram = {
mounted() {
this.handleEvent("draw", ({spec}) => {
console.log("XY Diagram Hook")
vegaEmbed(this.el, spec)
.then((result) => result.view)
.catch((error) => console.error(error))
})
},
}
export {XyDiagram}
EX
defmodule Components.XyDiagram do
use Surface.LiveComponent
require Logger
prop data, :list, required: true
prop height, :decimal, default: 200
prop value_key, :atom, required: true
@impl true
def update(assigns, socket) do
data =
Enum.map(assigns.data, & %{x: &1.timestamp, y: &1[assigns.value_key]})
spec =
VegaLite.new(title: "Title", width: :container, height: :container, padding: 5)
|> VegaLite.data_from_values(data)
|> VegaLite.mark(:line)
|> VegaLite.encode_field(:x, "x", type: :temporal)
|> VegaLite.encode_field(:y, "y", type: :quantitative)
|> VegaLite.to_spec()
|> IO.inspect() # print looks good here :)
{:ok, push_event(socket, "draw", %{"spec" => spec})}
end
@impl true
def render(assigns) do
~H"""
<div style={"width:100%; height: 300px"} id="graph" :hook="XyDiagram" phx-update="ignore" />
"""
end
end
I am a bit lost and do not know what else to try or search for.
Can you spot what I am doing wrong here?
Most Liked
milangupta
This is how I have mine set up .. if it helps you.
assets/vendor/vega_lite.js
/* import vegaEmbed from "vega-embed"; */
/**
* A hook used to render graphics according to the given
* Vega-Lite specification.
*
* The hook expects a `vega_lite:<id>:init` event with `{ spec }` payload,
* where `spec` is the graphic definition as an object.
*
* Configuration:
*
* * `data-id` - plot id
*
*
* OPTIONS : FULL LIST @ https://github.com/vega/vega-embed#options
* Eg,
* actions: Boolean / Object
* Determines if action links ("Export as PNG/SVG", "View Source", "View Vega"
* (only for Vega-Lite), "Open in Vega Editor") are included with the embedded view. If the value is true,
* all action links will be shown and none if the value is false. This property can take a key-value mapping
* object that maps keys (export, source, compiled, editor) to boolean values for determining if each action
* link should be shown. By default, export, source, and editor are true and compiled is false. These defaults
* can be overridden: for example, if actions is {export: false, source: true}, the embedded visualization
* will have two links – "View Source" and "Open in Vega Editor". The export property can take a key-value
* mapping object that maps keys (svg, png) to boolean values for determining if each export action
* link should be shown. By default, svg and png are true.
*/
const VegaLite = {
mounted() {
this.id = this.el.getAttribute("data-id");
this.viewPromise = null;
const container = document.createElement("div");
this.el.appendChild(container);
this.handleEvent(`vega_lite:${this.id}:init`, ({ spec }) => {
this.viewPromise = vegaEmbed(container, spec, {"actions": false})
.then((result) => result.view)
.catch((error) => {
console.error(
`Failed to render the given Vega-Lite specification, got the following error:\n\n ${error.message}\n\nMake sure to check for typos.`
);
});
});
},
destroyed() {
if (this.viewPromise) {
this.viewPromise.then((view) => view.finalize());
}
},
};
export default VegaLite;
assets/js/app.js
import VegaLite from '../vendor/vega_lite';
...
Hooks.VegaLite = VegaLite;
mix.exs
{:vega_lite, "~> 0.1.2"},
1
Popular in Questions
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service.
Currently when I de...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
Hi All,
I set a environment variables in dev.exs , like below code.
when i start server, how can i set the ${enable} value?
thanks.
d...
New
After calling mix ecto.create I get this error:
17:00:32.162 [error] GenServer #PID<0.412.0> terminating
** (Postgrex.Error) FATAL...
New
Hey all,
I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this:
...
New
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar.
I p...
New
Other popular topics
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!)
This post collects co...
New
Hi All,
I set a environment variables in dev.exs , like below code.
when i start server, how can i set the ${enable} value?
thanks.
d...
New
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
Hello, how can I check the Phoenix version ?
Thanks !
New
What learn first? Rust or Elixir
Hi Elixir community!
I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum.
...
New
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









