Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

234
Vistas
How can you draw a collection of lines and points based on categorical data in D3?

I am new to JavaScript/D3, and I am trying to code a relatively simple visualization based on some toy data I have, but cannot figure it out. This is the toy data:

toy_data = {
  'abstract' : ['a'],
  'introduction' : ['b', 'c'],
  'methods' : ['d', 'e', 'f'],
  'findings' : ['g', 'h', 'i', 'j'],
  'conclusion' : ['k', 'l', 'm', 'n', 'o']
  }

I want to write a function that takes in data formatted like this (or in a slightly different way, if necessary) and generates a visualization in D3 that looks roughly like the following (I generated this plot in Altair using similar data):

enter image description here

The difference would be that the x axis labels would correspond to the terms specified in my toy data, and I would only have as many circles as there are items in each associated key-value pair (e.g. 1 circle for abstract, 2 for introduction, 3 for methods, etc.). Eventually, I also will add additional data to control the size of the circles as in the image above, but for the moment I am satisfied with just a function that can take in any data of this form and at least generate a prototype with circles of the same size.

I feel like this should be fairly doable in D3, perhaps by defining a scatter plot and then adding connecting horizontal lines, or by combining a line plot and scatter plot, but I cannot figure out how to do it. If someone can explain and give an example of how to achieve this behavior, that would be extremely helpful, as I think I can build off of it to achieve what I want.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

This will get you started, though I'd suggest you rework your data. Most D3 patterns begin with either arrays of arrays or arrays of objects. Objects containing arrays of various lengths will be difficult to work with.

const toy_data = {
  'abstract' : ['a'],
  'introduction' : ['b', 'c'],
  'methods' : ['d', 'e', 'f'],
  'findings' : ['g', 'h', 'i', 'j'],
  'conclusion' : ['k', 'l', 'm', 'n', 'o']
  }
  
 const margin = {top:10,left:90,bottom:25,right:10},
  width = 480 - margin.top - margin.bottom,
  height = 250 - margin.left - margin.right;
  
 const svg = d3.select('#chart')
  .append('svg')
  .attr('width', width + margin.left + margin.right)
  .attr('height', height + margin.top + margin.bottom)
  .append('g')
  .attr('transform','translate(' + margin.left + ',' + margin.top + ')')
 
 let rows = Object.getOwnPropertyNames(toy_data) 
 let cols = [];
 

 for(prop in toy_data) {
  cols = cols.concat(toy_data[prop])
 }
 const x = d3.scaleBand()
  .domain(cols)
  .range([0,width])
  
 const y = d3.scaleBand()
  .domain(rows)
  .range([0,height])
  
 svg.append('g')
  .call(d3.axisLeft(y))
 
 svg.append('g')
  .attr('transform','translate(0,' + height + ')')
  .call(d3.axisBottom(x))
  
for(prop in toy_data) {

  svg.selectAll(null)
    .data(toy_data[prop])
    .enter()
    .append('circle')
    .attr('cx', d => x(d) + x.bandwidth()/2)
    .attr('cy', y(prop) + y.bandwidth()/2)
    .attr('r', x.bandwidth()/4)
    .style('fill','steelblue')

}
 
 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chart"><div>

UPDATE: I don't know the constraints of your data, but strictly from a D3 perspective, this would be easier to work with:

const toy_data = {
  'abstract' : ['a'],
  'introduction' : ['b', 'c'],
  'methods' : ['d', 'e', 'f'],
  'findings' : ['g', 'h', 'i', 'j'],
  'conclusion' : ['k', 'l', 'm', 'n', 'o']
 }
 
 let d3_data = [];
 for(prop in toy_data) {
   d3_data = d3_data.concat(toy_data[prop].map(d=> [prop, d]))
 }
 

      

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda