A fazer um gráfico de linhas em D3.js v. 5
chegou a hora de aumentar o nosso jogo e criar um gráfico de linha a partir do zero. E não apenas qualquer Gráfico de linhas: um gráfico de várias séries que pode acomodar qualquer número de linhas. Além de lidar com várias linhas, trabalharemos com escalas de tempo e lineares, eixos e rótulos – ou melhor, fazê-los trabalhar para nós. Há muito que fazer, por isso sugiro que dispares do teu servidor D3 e vamos começar.Vamos criar esta beleza! Divertido!
preparação do documento
como o primeiro passo que precisamos para preparar os dados e a estrutura do arquivo para a visualização. Criar um ‘line_chart’.html, styles.css, and data.csv na sua pasta de projecto e preencha-os com os excertos que se seguem. Isto vai fazer-nos começar.
Cole isto no “line_chart”.ficheiro html. O código define o elemento svg para nós para que possamos começar a desenhar imediatamente. Eu também criei uma estrutura básica à frente para que seja mais fácil navegar no documento enquanto trabalhamos em suas seções particulares.
deixar os estilos.documento css vazio por agora. Colar as seguintes linhas aos dados.csv. O gráfico de linhas contará com várias séries: correspondentes às colunas A, B E C.
date,A,B,C20-Jul-2019,10,20,1621-Jul-2019,11,22,1822-Jul-2019,13,19,2123-Jul-2019,11,17,2224-Jul-2019,15,16,2025-Jul-2019,16,19,1826-Jul-2019,19,21,1827-Jul-2019,22,25,1528-Jul-2019,18,24,1229-Jul-2019,14,20,1630-Jul-2019,14,18,1831-Jul-2019,16,18,2101-Aug-2019,15,20,2202-Aug-2019,14,21,19
preparação de dados
o primeiro passo – e um passo crucial para toda a visualização-é ler correctamente os dados. Eu usei um exemplo multi-série por uma razão: embora seja bastante simples traçar um único caminho, lidar com várias linhas (especialmente um número indefinido delas) requer um pouco mais de finesse D3. Colar o seguinte na secção de dados, reler o documento html e rever o registo da consola no seu navegador:
const timeConv = d3.timeParse("%d-%b-%Y");const dataset = d3.csv("data.csv");dataset.then(function(data) { const slices = data.columns.slice(1).map(function(id) { return { id: id, values: data.map(function(d){ return { date: timeConv(d.date), measurement: +d }; }) }; });console.log("Column headers", data.columns);console.log("Column headers without date", data.columns.slice(1));// returns the sliced datasetconsole.log("Slices",slices); // returns the first sliceconsole.log("First slice",slices);// returns the array in the first sliceconsole.log("A array",slices.values); // returns the date of the first row in the first sliceconsole.log("Date element",slices.values.date); // returns the array's lengthconsole.log("Array length",(slices.values).length);
vamos rever as transformações chamadas em nosso conjunto de dados um por um: – dados.as colunas devolve os dados dos cabeçalhos do csv.coluna.o slice (1) devolve os cabeçalhos csv sem a coluna de data (a fatia começa na coluna indexada em 1) – map () chama uma função em cada elemento da lista (consistindo em A, B E C) – Vamos chamar a cada um desses elementos um ‘slice’– map () atribui o nome da coluna como um elemento id para cada fatia– então atribui uma lista de valores a cada fatia– note como o elemento valores evoca uma função. Aqui nós mapeamos informações do conjunto de dados originais: o array consistirá de 2 colunas, Data e medição. A data é derivada da primeira coluna (e transformada num formato de data), e a medida é retirada da coluna correspondente à fatia id.At o fim dessas transformações temos 3 matrizes: A, B E C, com 2 colunas cada: data e medida. Esta é uma maneira incrivelmente flexível de cortar um conjunto de dados: independentemente de quantas colunas ele tem! Está tudo feito nessas poucas filas. Imprimi algumas informações na consola para te ajudar a rever o excerto.
preparação de escalas
depois que os dados foram lidos em precisamos configurar o mecanismo de escala. Isto é feito para imprimir o gráfico de acordo com os imóveis do svg. Escalas transformam a entrada de dados (nossas datas e valores) para coordenadas no plano svg. Cole as seguintes linhas na secção de escalas.
const xScale = d3.scaleTime().range();const yScale = d3.scaleLinear().rangeRound();xScale.domain(d3.extent(data, function(d){ return timeConv(d.date)}));yScale.domain();
vamos traçar as datas no eixo x e os valores no eixo Y. D3 provides a scaleTime () method for scaling dates, and a scaleLinear () method for continuous values. Primeiro decidimos o intervalo da escala: para que os valores de entrada devem ser traduzidos. Neste caso, vamos esticar os valores de dados de 0 para a largura do svg, e os valores numéricos a partir da altura do svg para 0. Como segundo passo, especificamos o domínio de dados de entrada. Um domínio consiste de todos os valores entre um mínimo especificado e máximo que um conjunto de dados pode tomar. Em vez de procurar manualmente esses valores, passamos através dele construído em funções D3:– d3.o extent () devolve um valor mínimo e máximo de um array (numa ordem natural) – isto irá funcionar perfeitamente no nosso conjunto de datas– d3.o max () devolve um valor máximo da lista. Note Como neste exemplo nós primeiro extraímos um valor máximo de cada array para então selecionar um máximo de todos os três. Eu também adicionei 4 ao valor máximo por razões estéticas puramente subjetivas: eu queria ter algum espaço acima do gráfico.
as balanças estão agora colocadas. Se você não tem escamas suficientes e gostaria de ver mais exemplos, dê uma olhada no meu tutorial anterior.
uma escala bem configurada permite – nos começar a traçar valores no svg. Cada vez que evocamos o conjunto de dados, só precisamos chamar uma escala apropriada sobre ele.Já chega de conversa – vamos desenhar alguma coisa! Os eixos são um bom ponto de partida: se traçados corretamente, eles nos garantirão que os dados foram lidos como esperado e que escalam tão bem quanto imaginamos.
Colar isto aos Eixos sob a secção de Preparação:
const yaxis = d3.axisLeft().scale(yScale); const xaxis = d3.axisBottom().scale(xScale);
e isto aos Eixos sob a secção de desenho:
svg.append("g") .attr("class", "axis") .attr("transform", "translate(0," + height + ")") .call(xaxis);svg.append("g") .attr("class", "axis") .call(yaxis);
e tão simples quanto isso nós traçamos os eixos x e y!Os eixos estão aqui!Reconhecidamente, os eixos não são os mais elegantes do mundo (há alguns eixos bonitos lá fora), mas estão aqui! Existem alguns ajustes adicionais que podemos aplicar para torná-los mais amigáveis para o leitor.
vamos olhar primeiro para o eixo x: há algo engraçado acontecendo com as datas. Lendo a partir da esquerda, temos ‘Sat 20′,’ Jul 21′,’ Mon 22′, e em algum momento chegamos apenas’agosto’. Parece que os meses e os dias chegaram numa mistura insubordinada de variações. Temos de pôr fim a este estilo livre, e com isto quero dizer que devemos decidir qual o formato de data que gostaríamos de imprimir no ecrã. O d3.o método axis () nos permite ajustar todo o tipo de coisas para carrapatos-seu número, intervalo entre os pontos, formato de exibição, etc. Vamos configurar alguns deles para ambos os eixos.
substituir a definição dos eixos na secção de Preparação pelo seguinte excerto e actualizar a visualização:
const yaxis = d3.axisLeft() .ticks((slices.values).length) .scale(yScale);const xaxis = d3.axisBottom() .ticks(d3.timeDay.every(1)) .tickFormat(d3.timeFormat('%b %d')) .scale(xScale);
o código acima especifica um conjunto de carrapatos para o eixo y (14, ou tantos quantos existem elementos array / linhas csv). No caso do eixo x um carrapato será exibido com uma granularidade de um dia, todos os dias. Isso foi conseguido ajustando a propriedade da carraça para d3.timeDay.every (1). O formato das datas apresentadas irá mostrar o dia e o mês abreviado para cada carrapato. Depois dessas mudanças acabamos com eixos um pouco melhorados: