如何在图表的每个点上添加带有值的标签?

时间:2018-12-25 16:42:43

标签: javascript d3.js charts

我有一个折线图,其中x表示时间刻度,y表示值。 https://jsfiddle.net/gh6t04w2/21/

const margin = {top:50, right:0, bottom:88, left: 50};
const width = window.innerWidth * 0.8;
const height = window.innerHeight * 0.9;

const innerWidth = width - margin.left - margin.right;
const innerHeight = 300;//height - margin.top - margin.bottom;
  console.log(height);
const svg = d3.select('#chart').append('svg')
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);



d3.timeFormatDefaultLocale({
  "dateTime": "%A, %e %B %Y г. %X",
  "date": "%d.%m.%Y",
  "time": "%H:%M:%S",
  "periods": ["AM", "PM"],
  "days": ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"],
  "shortDays": ["вс", "пн", "вт", "ср", "чт", "пт", "сб"],
  "months": ["январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"],
  "shortMonths": ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"]
});

const render = data => {
  const title = 'Доходность РФ'
  const xValue = d=> d.timestamp;
  const yValue = d=> d.growth;
  const xAxisLabel = '';
  const yAxisLabel = 'Доходность, %';
  const circleRadius = 4;
  const circleOpacityHover = 0.6;
  const circleOpacity = 0.8;
  const circleRadiusHover = 10;
  const duration = 250;


  

  const xScale = d3.scaleTime()
    .domain(d3.extent(data, xValue))
    .range([0, innerWidth])
    .nice();

  const yScale = d3.scaleLinear()
    .domain(d3.extent(data, yValue))
    .range([innerHeight, 0])
    .nice();

  const g = svg.append('g')
      .attr('transform', `translate(${margin.left},${margin.top})`);
  

 const yAxisTickFormat = number =>
    d3.format("")(number * 100);
      

  const xAxis = d3.axisBottom(xScale)
    .ticks(8)
    .tickSize(-innerHeight)
    .tickPadding(15);

   const yAxis = d3.axisLeft(yScale)
    .tickFormat(yAxisTickFormat)
    .tickSize(-innerWidth)
    .tickPadding(10);

  const yAxisG = g.append('g').call(yAxis);
    yAxisG.selectAll('.domain').remove();

  const xAxisG = g.append('g').call(xAxis)
      .attr('transform', `translate(0, ${innerHeight})`)
       
yAxisG.append('text')
  .attr('class', 'axis-label')
  .attr('y', -60 )
  .attr('x', -innerHeight/2)
  .attr('transform', `rotate(-90)`)
  .attr('text-anchor', 'middle')
  .attr('fill', "black")
    .text(yAxisLabel);

  xAxisG.select('.domain').remove();

  xAxisG.append('text')
  .attr('class', 'axis-label')
  .attr('y', 75 )
  .attr('x', innerWidth/2)
  .attr('fill', "black")
    .text(xAxisLabel);

    const lineGenerator = d3.line()
      .x(d=> xScale(xValue(d)))
      .y(d=> yScale(yValue(d)));

    g.append('path')
    .attr('class', 'line-path')
    .attr('d', lineGenerator(data));



  g.selectAll('circle').data(data)
  .enter().append('circle')
    .attr('cy', d=> yScale(yValue(d)))
    .attr('cx', d=> xScale(xValue(d)))
    .attr('r', circleRadius)
    
    .on("mouseover", function(d) {
        d3.select(this)
          .transition()
          .duration(duration)
          .style('opacity', circleOpacityHover)
          .attr("r", circleRadiusHover);
      })
    .on("mouseout", function(d) {
        d3.select(this) 
          .transition()
          .style('opacity', circleOpacity)
          .duration(duration)
          .attr("r", circleRadius);  
      });

  //

    //

  g.append('text')
  .attr('y', -10 )
    .text(title);



};
const csvUrl = 'https://gist.githubusercontent.com/waitfornight6/b491f4146e104b78c12d5c65a5151aa3/raw/b629cc4921474bfe347c0ded14943c3e11d32bf2/data.csv';
d3.csv(csvUrl, onCsvLoaded);

function onCsvLoaded(data) {
  data.forEach(d => {
    const parts = d.timestamp.split('.');
      d.growth = +d.growth;
      d.timestamp = new Date(parts[2], parts[0]-1, parts[1]);
    });
  console.log(data);
  render(data);
}
  

//Table
body {
	margin: 0px;
	overflow: hidden;
}

circle {
	fill: steelblue;
}

.line-path {
	fill:none;
	stroke: steelblue;
	stroke-width: 2;
	stroke-linejoin: round;
}

text {
	font-size: 2em;
	font-family: sans-serif;

}

.tick text {
  fill: #8E8883;
  font-size: 1.7em;

}

.tick line {
  stroke: #C0C0BB;

}

.axis-label {
	font-size: 2em;
	fill: #635F5D;
}

.title {
  font-size: 3.7em;
  fill: #635F5D;
}

#chart {height:500px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id="chart"></div>

我需要为图表的每个点添加标签,如此处http://bl.ocks.org/bobmonteverde/2070123

我是d3的初学者,我曾尝试将labael文本添加到圈子中,但这没有用。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用 d3-tip 模块。在 GitHub https://github.com/Caged/d3-tip上关注它。

您还可以在此处找到用法的基本示例:http://bl.ocks.org/davegotz/bd54b56723c154d25eedde6504d30ad7

我已经更新了您的jsfiddle:

  • 添加了d3-tip库并初始化了d3-tip:

  const tool_tip = d3.tip()
  .attr("class", "d3-tip")
  .html(d => d.growth*100 + ", " + d.timestamp.getDate() + '/' + (d.timestamp.getMonth()+1) + '/' + d.timestamp.getFullYear());
g.call(tool_tip);

  • 使用工具提示合并鼠标事件:

g.selectAll('circle').data(data)
  .enter().append('circle')
    .attr('cy', d=> yScale(yValue(d)))
    .attr('cx', d=> xScale(xValue(d)))
    .attr('r', circleRadius)
    .on("mouseover", mouseover)
    .on("mouseout", mouseout);
function mouseover (d,i){
          d3.select(this)
            .transition()
            .duration(duration)
            .style('opacity', circleOpacityHover)
            .attr("r", circleRadiusHover);
           tool_tip.show(d,this)
            }
            
function mouseout (d,i){
         d3.select(this) 
            .transition()
            .style('opacity', circleOpacity)
            .duration(duration)
            .attr("r", circleRadius);  
           tool_tip.hide(d,this)}

  • 更新后的CSS

.d3-tip {
      line-height: 1;
      padding: 6px;
      background: rgba(0, 0, 0, 0.8);
      color: #fff;
      border-radius: 4px;
      font-size: 12px;
    }

您可以在此处查看更新的小提琴:https://jsfiddle.net/liubomyr_gavryliv/p95zjb0d/

真诚的