javascript - 如何使用 chartist js 在同一图表中相对拉伸(stretch)两个具有不同数量索引的系列?

标签 javascript graph charts chartist.js

前奏

使用 Chartist 我知道有一个选项可以在两个不同的数据集中“填补漏洞”,这两个数据集的项目数量不相等,如下例所示:

var chart = new Chartist.Line('.ct-chart', {
  labels: [1, 2, 3, 4, 5, 6, 7],
  series: [
    [5, 5, 10, 8, 7, 5, 4],
    [10, 15, null, 12, null, null, null]
  ]
}, {
  lineSmooth: Chartist.Interpolation.cardinal({
    fillHoles: true,
  })
});
<script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
<link href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css" rel="stylesheet"/>
<div class="ct-chart"></div>

请注意示例中的第二个系列将只显示一行到最后一个非 null 的值(在索引 4 处)。

问题

有没有办法让图表师将第二个系列相对于第一个系列展开,将第二个系列线展开以匹配第一个系列,直到最长系列的最后一个值?

最佳答案

您可以编写一些帮助器来修改您的数据数组:

  • trimNulls 从数组的开头和结尾删除所有 null 值:

    [10, 15, null, 12, null, null, null] -> [10, 15, null, 12]
    
  • stretch 获取一个数组和所需的长度,并将原始值分配给新索引:

    [10, 15, null, 12] -> 7 -> [10, null, 15, null, null, null, 12]
    
  • alignSeries 获取一系列数据系列并将它们中的每一个与最宽的系列对齐。

    [ [ 1, 2, 3, 4], [1, 4], [null, 1, 4] ] -> 
      [ [ 1, 2, 3, 4], [1, null, null, 4], [1, null, null, 4] ]
    

在运行示例中,包含旧行以供引用:

const trimNulls = (data) => {
  // Find the first non-null value
  const start = data.findIndex(y => y !== null);
  // Find the last non-null value
  const end = data.length - Array.from(data).reverse()
                                 .findIndex(y => y !== null);
  // Return the elements between those boundaries                               
  return data.slice(start, end);
}

const stretch = (data, newLength) => {
  // Create array of required number of nulls
  const stretched = Array(newLength).fill(null);
  // Determine the stretch factor
  const s = newLength / data.length;
  // For every value we want to keep, place it
  // at its new, stretched index
  data.forEach((y, x) => {
    stretched[Math.ceil(x * s)] = y;
  });
  // Return the newly created array
  return stretched;
}

// Takes a list of series and aligns their starts and ends, stretching 
// in between
const alignSeries = series => {
  // Trim each series
  const trimmed = series.map(trimNulls);
  // Find the longest one
  const maxLength = Math.max(...trimmed.map(t => t.length));
  // Stretch all series to the longest length and return
  return trimmed.map(t => stretch(t, maxLength));
};

var chart = new Chartist.Line('.ct-chart', {
  labels: [1, 2, 3, 4, 5, 6, 7],
  series: [
    ...alignSeries([
      [5, 5, 10, 8, 7, 5, 4],
      [10, 15, null, 12, null, null, null]
    ]),
    // For reference
    [10, 15, null, 12, null, null, null]
  ]
}, {
  lineSmooth: Chartist.Interpolation.cardinal({
    fillHoles: true,
  })
});
<script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
<link href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css" rel="stylesheet"/>
<div class="ct-chart"></div>

关于javascript - 如何使用 chartist js 在同一图表中相对拉伸(stretch)两个具有不同数量索引的系列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52945603/

相关文章:

javascript - 如何关闭文件夹的 fs.watch 监听器

java - 如何在图表引擎中缓慢绘制图表

extjs 4折线图渲染问题

javascript - Testrpc 错误:在 Mac 上监听 EADDRINUSE:::8545

javascript - 如果react-router-dom不匹配任何路由,则页面重新加载

python - 为什么我的 Python 散点图不起作用?

r - ggplot2 在彩色线条之上添加彩色形状并将两者组合成一个图例

javascript - Chart.js 数字格式

javascript - 加载 Google LineChart 动画

javascript - 无法使用javascript更改href的值