function displayTestAndEnvironmentChart()

in hack/jenkins/test-flake-chart/flake_chart.js [249:383]


function displayTestAndEnvironmentChart(testData, testName, environmentName) {
  const testRuns = testData
    // Filter to only contain unskipped runs of the requested test and requested environment.
    .filter(test => test.name === testName && test.environment === environmentName && test.status !== testStatus.SKIPPED);
  const chartsContainer = document.getElementById('chart_div');
  {
    const data = new google.visualization.DataTable();
    data.addColumn('date', 'Date');
    data.addColumn('number', 'Flake Percentage');
    data.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });
    data.addColumn('number', 'Duration');
    data.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });

    data.addRows(
      aggregateRuns(testRuns)
        .map(groupData => [
          groupData.date,
          groupData.flakeRate,
          `<div style="padding: 1rem; font-family: 'Arial'; font-size: 14">
            <b>Date:</b> ${groupData.date.toLocaleString([], {dateStyle: 'medium'})}<br>
            <b>Flake Percentage:</b> ${groupData.flakeRate.toFixed(2)}%<br>
            <b>Jobs:</b><br>
            ${groupData.jobs.map(({ id, status }) => `  - <a href="${testGopoghLink(id, environmentName, testName)}">${id}</a> (${status})`).join("<br>")}
          </div>`,
          groupData.duration,
          `<div style="padding: 1rem; font-family: 'Arial'; font-size: 14">
            <b>Date:</b> ${groupData.date.toLocaleString([], {dateStyle: 'medium'})}<br>
            <b>Average Duration:</b> ${groupData.duration.toFixed(2)}s<br>
            <b>Jobs:</b><br>
            ${groupData.jobs.map(({ id, duration }) => `  - <a href="${testGopoghLink(id, environmentName, testName)}">${id}</a> (${duration}s)`).join("<br>")}
          </div>`,
        ])
    );

    const options = {
      title: `Flake rate and duration by day of ${testName} on ${environmentName}`,
      width: window.innerWidth,
      height: window.innerHeight,
      pointSize: 10,
      pointShape: "circle",
      series: {
        0: { targetAxisIndex: 0 },
        1: { targetAxisIndex: 1 },
      },
      vAxes: {
        0: { title: "Flake rate", minValue: 0, maxValue: 100 },
        1: { title: "Duration (seconds)" },
      },
      colors: ['#dc3912', '#3366cc'],
      tooltip: { trigger: "selection", isHtml: true }
    };
    const flakeRateContainer = document.createElement("div");
    flakeRateContainer.style.width = "100vw";
    flakeRateContainer.style.height = "100vh";
    chartsContainer.appendChild(flakeRateContainer);
    const chart = new google.visualization.LineChart(flakeRateContainer);
    chart.draw(data, options);
  }
  {
    const dates = testRuns.map(run => run.date.getTime());
    const startDate = new Date(dates.min());
    const endDate = new Date(dates.max());
  
    const weekDates = [];
    let currentDate = startDate;
    while (currentDate < endDate) {
      weekDates.push(currentDate);
      currentDate = new Date(currentDate);
      currentDate.setDate(currentDate.getDate() + 7);
    }
    weekDates.push(currentDate);
    weekDates.findRounded = function (value) {
      let index = this.findIndex(v => value < v);
      if (index == 0) {
        return this[index];
      }
      if (index < 0) {
        index = this.length;
      }
      return this[index - 1];
    }

    const data = new google.visualization.DataTable();
    data.addColumn('date', 'Date');
    data.addColumn('number', 'Flake Percentage');
    data.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });
    data.addColumn('number', 'Duration');
    data.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } });

    data.addRows(
      aggregateWeeklyRuns(testRuns, weekDates)
        .map(groupData => [
          groupData.date,
          groupData.flakeRate,
          `<div style="padding: 1rem; font-family: 'Arial'; font-size: 14">
            <b>Date:</b> ${groupData.date.toLocaleString([], {dateStyle: 'medium'})}<br>
            <b>Flake Percentage:</b> ${groupData.flakeRate.toFixed(2)}%<br>
            <b>Jobs:</b><br>
            ${groupData.jobs.map(({ id, status }) => `  - <a href="${testGopoghLink(id, environmentName, testName)}">${id}</a> (${status})`).join("<br>")}
          </div>`,
          groupData.duration,
          `<div style="padding: 1rem; font-family: 'Arial'; font-size: 14">
            <b>Date:</b> ${groupData.date.toLocaleString([], {dateStyle: 'medium'})}<br>
            <b>Average Duration:</b> ${groupData.duration.toFixed(2)}s<br>
            <b>Jobs:</b><br>
            ${groupData.jobs.map(({ id, duration }) => `  - <a href="${testGopoghLink(id, environmentName, testName)}">${id}</a> (${duration}s)`).join("<br>")}
          </div>`,
        ])
    );

    const options = {
      title: `Flake rate and duration by week of ${testName} on ${environmentName}`,
      width: window.innerWidth,
      height: window.innerHeight,
      pointSize: 10,
      pointShape: "circle",
      series: {
        0: { targetAxisIndex: 0 },
        1: { targetAxisIndex: 1 },
      },
      vAxes: {
        0: { title: "Flake rate", minValue: 0, maxValue: 100 },
        1: { title: "Duration (seconds)" },
      },
      colors: ['#dc3912', '#3366cc'],
      tooltip: { trigger: "selection", isHtml: true }
    };
    const flakeRateContainer = document.createElement("div");
    flakeRateContainer.style.width = "100vw";
    flakeRateContainer.style.height = "100vh";
    chartsContainer.appendChild(flakeRateContainer);
    const chart = new google.visualization.LineChart(flakeRateContainer);
    chart.draw(data, options);
  }
}