Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

167
Views
Problema de deformación del gráfico circular de lienzo de JavaScript

Estoy tratando de crear un elemento HTML personalizado que me permita crear gráficos circulares fácilmente. He tenido mucho éxito hasta ahora, excepto por el hecho de que parece que no puedo lograr que el dibujo del lienzo real tenga las proporciones correctas.

 class PieChart extends HTMLElement { constructor(){ super(); } connectedCallback(){ this.classList.add('pie-chart') this.innerHTML = `<canvas style="width:100%; height:100%;"></canvas>` this.style.display = 'block' this.ctx = this.getElementsByTagName('canvas')[0].getContext('2d') const results = [ {mood: "Angry", total: 1599, shade: "#0a9627"}, {mood: "Happy", total: 478, shade: "#960A2C"}, {mood: "Melancholic", total:332, shade: "#332E2E"}, {mood: "Gloomy", total: 195, shade: "#F73809"}, {mood: "Eh", total: 195, shade: "#000000"} ]; this.chartify(results); } chartify(results){ var el_width = this.getBoundingClientRect().width; var half = (el_width / 2); let sum = 0; let portion = results.reduce((sum, {total}) => sum + total, 0); let currentAngle = 0; for (let moodValue of results) { //calculating the angle the slice (portion) will take in the chart let portionAngle = (moodValue.total / portion) * 2 * Math.PI; //drawing an arc and a line to the center to differentiate the slice from the rest this.ctx.beginPath(); this.ctx.arc(half, half, half, currentAngle, currentAngle + portionAngle); currentAngle += portionAngle; this.ctx.lineTo(half, half); //filling the slices with the corresponding mood's color this.ctx.fillStyle = moodValue.shade; this.ctx.fill(); } } } window.customElements.define('pie-chart', PieChart); export{PieChart};

este es el resultado devuelto

ingrese la descripción de la imagen aquí

El elemento personalizado está diseñado para tener un tamaño dinámico. Entonces, para dibujar los arcos, dividí el ancho por 2 para obtener el punto medio. Pensé que esto también sería el radio. entonces todo lo que necesito es calcular el ángulo con el que no tengo ningún problema. ¿Por qué el gráfico circular es oblongo y no ocupa todo el espacio? ¿Qué estoy haciendo mal en mi código de dibujo de lienzo?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

El elemento canvas tiene valores predeterminados para sus atributos de height y width de 150 y 300 , respectivamente. Si necesita que su lienzo sea cuadrado, debe especificar que estos tamaños sean iguales.

Este ejemplo modifica su variable el_width para leer el ancho del lienzo directamente, en lugar de usar getBoundingClientRect . También modifiqué la forma en que se crea el elemento de canvas para que tenga atributos de width y height , y sus estilos de ancho y alto al 100% se configuran a través de CSS:

 class PieChart extends HTMLElement { constructor(){ super(); } connectedCallback(){ this.classList.add('pie-chart') this.innerHTML = `<canvas width="300" height="300"></canvas>` this.style.display = 'block' this.ctx = this.getElementsByTagName('canvas')[0].getContext('2d') const results = [ {mood: "Angry", total: 1599, shade: "#0a9627"}, {mood: "Happy", total: 478, shade: "#960A2C"}, {mood: "Melancholic", total:332, shade: "#332E2E"}, {mood: "Gloomy", total: 195, shade: "#F73809"}, {mood: "Eh", total: 195, shade: "#000000"} ]; this.chartify(results); } chartify(results){ var el_width = this.ctx.canvas.width; var half = (el_width / 2); let sum = 0; let portion = results.reduce((sum, {total}) => sum + total, 0); let currentAngle = 0; for (let moodValue of results) { //calculating the angle the slice (portion) will take in the chart let portionAngle = (moodValue.total / portion) * 2 * Math.PI; //drawing an arc and a line to the center to differentiate the slice from the rest this.ctx.beginPath(); this.ctx.arc(half, half, half, currentAngle, currentAngle + portionAngle); currentAngle += portionAngle; this.ctx.lineTo(half, half); //filling the slices with the corresponding mood's color this.ctx.fillStyle = moodValue.shade; this.ctx.fill(); } } } window.customElements.define('pie-chart', PieChart);
 pie-chart { width: 150px; aspect-ratio: 1 / 1; } pie-chart canvas { width: 100%; height: 100%; }
 <pie-chart></pie-chart>

También notará que si usa valores de width y height que son más pequeños que el tamaño real en el que se muestra el lienzo, se ampliará notablemente ya que está produciendo una imagen rasterizada en lugar de una vectorial.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!