Having difficulty creating a shadow beneath a canvas displaying Vega charts

I'm looking to create a floating effect for my chart by adding shadows to the canvas element that holds it. Despite trying various methods, I can't seem to get the shadow effect to work.

Here is the code snippet I have for adding shadows:

<script>
document.addEventListener('DOMContentLoaded', function() {
var canvas = document.getElementsByClassName("marks")[0];
if (canvas.getContext)
    {
      var ctx = canvas.getContext('2d');
      ctx.shadowColor = 'black';
      ctx.shadowBlur = 10;
      ctx.shadowOffsetX = 20;
      ctx.shadowOffsetY = 20;
    //  ctx.fill();
    }
}, false);
</script>

This is how the complete HTML structure looks like -

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
  <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8dfbe8eaeca0e1e4f9e8cdb9a3b5a3bc">[email protected]</a>"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-projection-extended@2"></script>
</head>
<body>
<div id="vis"></div>
  <script type="text/javascript">
    var spec = {
      "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
      "config": {
        "view": {
          "continuousHeight": 300,
          "continuousWidth": 400
        }
      },
      "data": {
        "url": "https://vega.github.io/vega-datasets/data/cars.json"
      },
      "encoding": {
        "color": {
          "field": "Origin",
          "type": "nominal"
        },
        "x": {
          "field": "Horsepower",
          "type": "quantitative"
        },
        "y": {
          "field": "Miles_per_Gallon",
          "type": "quantitative"
        }
      },
      "mark": "point"
    };
    var opt = {"renderer": "canvas", "actions": false};
    vegaEmbed("#vis", spec, opt);
  </script>

<span class="update_time">Updated at 2020-02-24 12:10</span>

</body>
<script>
document.addEventListener('DOMContentLoaded', function() {
var canvas = document.getElementsByClassName("marks")[0];
if (canvas.getContext)
    {
      var ctx = canvas.getContext('2d');
      ctx.shadowColor = 'black';
      ctx.shadowBlur = 10;
      ctx.shadowOffsetX = 20;
      ctx.shadowOffsetY = 20;
    //  ctx.fill();
    }
}, false);
</script>
</html>

What adjustments do I need to make in the script to add a shadow effect below one side of the chart?

Answer №1

When dealing with the HTML element canvas, you can modify its display using CSS and the box-shadow property.

It's important to note that having content between the closing body tag and the closing html tag is not valid. If you find yourself needing a final script element (which isn't required here), it should be right before the closing body tag.

The line:

var canvas = document.getElementsByClassName("marks")[0];

may not be the most efficient way to reference your DOM element, as discussed in more detail here. Alternatively, consider using:

var canvas = document.querySelector(".marks");

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
  <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e197848680cc8d889584a1d5cfd9cfd0">[email protected]</a>"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-projection-extended@2"></script>

  <style>
    canvas { border:1px solid black; box-shadow: 4px 4px 1px grey; }
  </style>

</head>
<body>
<div id="vis"></div>
  <script>
    var spec = {
      "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
      "config": {
        "view": {
          "continuousHeight": 300,
          "continuousWidth": 400
        }
      },
      "data": {
        "url": "https://vega.github.io/vega-datasets/data/cars.json"
      },
      "encoding": {
        "color": {
          "field": "Origin",
          "type": "nominal"
        },
        "x": {
          "field": "Horsepower",
          "type": "quantitative"
        },
        "y": {
          "field": "Miles_per_Gallon",
          "type": "quantitative"
        }
      },
      "mark": "point"
    };
    var opt = {"renderer": "canvas", "actions": false};
    vegaEmbed("#vis", spec, opt);
  </script>

  <div class="update_time">Updated at 2020-02-24 12:10</div>
</body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Simulating dynamic route parameters in the Next 13 application directory

I am currently working with Jest and testing library to conduct unit tests on my NextJS application. I am facing difficulties in rendering a page on a dynamic path. Here is the code for my page/component: export default async function MyPage({ params }: { ...

Issue encountered while attempting to host an ejs file using Express in Node.js

I'm encountering an issue while attempting to serve an .ejs file using express. The error I'm getting is as follows: Error: No default engine was specified and no extension was provided. at new View (C:\development\dashboard& ...

Is there a way to dynamically adjust @keyframes properties through JavaScript?

I am looking to dynamically change the top value of the keyframes based on a JavaScript variable x. While I have experience changing CSS with JavaScript, this particular challenge has me stumped. Code: var x = Math.floor((Math.random() * 1080) + 1); ...

JavaScript Time Counter: Keeping Track of Time Dynamically

Currently, I am attempting to create a dynamic time counter/timer using JavaScript. Why dynamic? Well, my goal is to have the ability to display days/hours/minutes/seconds depending on the size of the timestamp provided. If the timestamp is less than a d ...

What is the best way to upload images in Vue.js without using base64 formatting?

Is there a way to upload an image file without it being base64 encoded? I currently can only achieve base64 format when trying to upload an image. How can I modify the code to allow for regular file uploads? <script> submitBox = new Vue({ el: "#su ...

Submitting data using JavaScript's POST method

I am facing a challenge with posting Array data to an HTTP connector. My data is structured as follows: var data = [{ key:'myKey', keyName:'myKeyName', value:'value', valueName:'valueName' }, { ...

Inability to update Vue.js component data even after a successful GET request

I am encountering an issue with a component that initially contains a default object, and then fetches a populated object via a GET request upon creation. Despite successfully updating this.profile within the method, the changes do not seem to propagate ...

Switch up the CSS variable within an embedded iframe

I'm in a predicament with a specific issue. I am currently utilizing Angular to incorporate an Iframe. Let's imagine the angular app as A and the Iframe as B. B is being loaded within A. Within B, I have utilized CSS variables to define colors. I ...

Retrieving JSON data in Angular 2

There are limited options available on SO, but it seems they are no longer viable. Angular 2 is constantly evolving... I am attempting to retrieve data from a JSON file in my project. The JSON file is named items.json. I am pondering if I can achieve th ...

Implementing pagination for a scrolling tab group with a flexible number of buttons

I need to implement a pagination feature in my scroll function where users can select from a list of tabs/buttons and it will automatically scroll to the corresponding div/tab. Currently, I have a while statement that generates songs from my database, with ...

Problem with escaping special characters in random string HTML

As I was in the process of creating a JavaScript tool to generate random strings, with or without special characters, I stumbled upon an inspiring snippet that caught my attention: (): function randStr(len) { let s = ''; while (len--) s += ...

Creating a dropdown navigation menu using jQuery

I have been experimenting with creating a customized Drop Down menu using ul li and Jquery, following this helpful Tutorial. Here is the sample HTML Code for testing: <div id="dd" class="wrapper-dropdown-3" tabindex="1"> <span>OS</span> ...

Placing two texts alongside a logo in a Bootstrap Navbar: Step-by-step guide

As I venture into the world of Bootstrap, I am on a quest to create a Navbar Component similar to this design: https://i.stack.imgur.com/NidKQ.png I attempted to use the Navbar Image and Text code, but encountered an issue where the text would only displ ...

PHP Form Submission Issue

I'm currently facing an issue with submitting a form using PHP and PHPMailer. Initially, I created a form based on the complete form example from w3schools. After that, I attempted to send the form via email by integrating PHPMailer, but unfortunatel ...

Could anyone provide an explanation of the current situation in this section of the code?

I am currently working on a piece of code that looks like this: ruter.get('/', async function (_, res) { const [categories, items] = (await Promise.all([ db.query('SELECT * FROM categories'), db.query('SELECT * FROM invento ...

AngularJS- issue with button visibility on 'toolbar' widget

In my angularJS application, there is a page with multiple widgets displayed. When a user clicks on the 'Settings' button on the page (separate from the widgets), a toolbar for each widget appears showing different buttons depending on the widget ...

The $resource.query function will now return an array of characters instead of a single string when splitting strings

Recently, I've been working on utilizing an Angular $resource in my project. Here's a snippet of the code: angular.module('app') .factory('data', function ($resource) { var Con = $resource('/api/data', {}, { ...

What situations warrant the use of unescaped !{} in pug for string interpolation?

Is there a practical application for utilizing !{} - string interpolation in an unescaped format, despite the potential risks associated with its use? I have reviewed the information provided at these sources: Using !{ } and #{ } interpolation in a jade ...

Using JQuery, remove any duplicate items from one list box and populate another list box

I have two list boxes set up: the leftBox contains all available options, while the rightBox displays the selected options. I am already familiar with how to add and remove items from each list box using jquery. However, my current goal is to automatically ...

Limit the length of text using jQuery by specifying the maximum pixel width

Trying to utilize jQuery for a quick function that calculates the pixel width of a string on an HTML page and then shortens the string until it reaches a desired pixel width... Unfortunately, I'm encountering issues with this process as the text is n ...