简体   繁体   中英

Appending multiple options to html in d3

I have a timeline in d3 which is using data from posts in Wordpress that are formatted in JSON. Items on the timeline have tooltips which display a few things, including start and end times for the item. Both the timeline and the tooltips are working fine except that I have two conditions that change what's displayed in the tooltip and I can only get one to work at a time.

The two conditions are:

  1. If the start date is the same as the end date, we just display the start date. Otherwise we display startDate + " to " + endDate.
  2. The date might be displayed as just the year, the month and year, or the day, month and year, depending on input from the post.

So I have three separate date formats (all working fine):

var displayDate = d3.time.format("%d %b %Y");
var displayMonthYear = d3.time.format("%b %Y");
var displayYear = d3.time.format("%Y");

And I can append html to the tooltip with either the first condition:

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset(function(d) { if (xTimeline(d.endDate)  > 800) { return [-10, 8] } else { return [-10, -8]  } })
  .html(function(d) {
    if ((xTimeline(d.endDate) - xTimeline(d.startDate) == 0)) {
      return d.title + "<br/><p>" + displayDate(d.startDate) + "</p>" + d.content; }
    else { 
      return d.title + "<br/><p>" + displayDate(d.startDate) + " to " + displayDate(d.endDate) + "</p>" + d.content; }
  });

Or the second:

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset(function(d) { if (xTimeline(d.endDate)  > 800) { return [-10, 8] } else { return [-10, -8]  } })
  .html(function(d) { if (d.dateFormat == "Year only") {
  return d.title + "<br/><p>" + displayYear(d.startDate) + "</p>" + d.content; 
  }
  else if (d.dateFormat == "Month and year") {
return d.title + "<br/><p>" + displayMonthYear(d.startDate) + "</p>" + d.content; 
  }
  else {
return d.title + "<br/><p>" + displayDate(d.startDate) + "</p>" + d.content; 
  }
  });

But I lack the skills to combine them. I've tried making the second one into a var or a function, but I can't seem to make it work.

I suspect this is really straightforward for someone with a good knowledge of Javascript, but that's not me at this stage.

Any help is greatly appreciated.

@tgerard: I deleted my previous answer after re-reading your question and realizing that I had not provided what you were asking for. I think the following code is what you were actually looking for:

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset(function(d) {
      if (xTimeline(d.endDate)  > 800) {
        return [-10, 8];
      } else {
        return [-10, -8];
      }
  })
  .html(function(d) {
    var toolTipContent = "";
    if ((xTimeline(d.endDate) - xTimeline(d.startDate) == 0)) {
      toolTipContent = getToolTipContent(d, true);
    } else {
      toolTipContent = getToolTipContent(d, false);
    }
    return toolTipContent;
  });

function getToolTipContent(d, sameDates) {
  var toolTipContent = d.title + "<br/><p>";
  if (d.dateFormat == "Year only") {
    toolTipContent +=  (sameDates)
      ? displayYear(d.startDate)
      : displayYear(d.startDate) + " to " + displayYear(d.endDate);
  } else if (d.dateFormat == "Month and year") {
    toolTipContent +=  (sameDates)
      ? displayMonthYear(d.startDate)
      : displayMonthYear(d.startDate) + " to " + displayMonthYear(d.endDate);
  } else {
    toolTipContent +=  (sameDates)
      ? displayDate(d.startDate)
      : displayDate(d.startDate) + " to " + displayDate(d.endDate);
  }
  toolTipContent += "</p>" + d.content;
  return toolTipContent;
}

Within the getToolTipContent function, we check three conditions for the date format:

  1. Year only
  2. Month and year
  3. Something else (full date)

Then for each one of those conditions, we use a ternary operator to decide what to append to the toolTipContent string. So, if 'sameDates' evaluates to true, the part after the '?' gets appended. If 'sameDates' evaluates to false, the part after the ':' gets appended.

Good luck with your project! Let me know if you have any questions about the code above.

I think you are looking for this, because from the question I understood like this, and giving it to you.

var text = '';

if ((xTimeline(d.endDate) - xTimeline(d.startDate) == 0)) {
   text+= d.title + "<br/><p>" + displayDate(d.startDate) + "</p>" + d.content; 
} else { 
   text+= d.title + "<br/><p>" + displayDate(d.startDate) + " to " + displayDate(d.endDate) + "</p>" + d.content; 
}

if (d.dateFormat == "Year only") {
   text += d.title + "<br/><p>" + displayYear(d.startDate) + "</p>" + d.content; 
} else if (d.dateFormat == "Month and year") {
   text += d.title + "<br/><p>" + displayMonthYear(d.startDate) + "</p>" + d.content; 
} else {
   text += d.title + "<br/><p>" + displayDate(d.startDate) + "</p>" + d.content; 
}

return text;

If you are not looking for this, ask me for more. what you exactly want to display either with screen shot or something so that I can get it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM