2

我想创建一个基于 vega lite API 的通用交叉过滤器。定量属性应显示为直方图,名义/有序属性应显示为条形图。

在这个可观察的(https://observablehq.com/@ee2dev/exploring-a-csv-file-with-vega-lite)中,我尝试实现它(参见单元格 vis3 - 最后一个可视化旁边)。

这是代码:

vis3 = {
  vl.vega.timeFormatLocale(locale); // show dates in German 
  vl.vega.formatLocale(locale); // show numbers with German groupings/ separators
  const brush = vl.selectInterval().encodings('x').resolve('intersect');

  // 1 histograms for quantitative data
  const hist1 = vl.markBar({tooltip: true}).encode(
    vl.x().fieldQ(vl.repeat('row'))
      //.bin({maxbins: 100, minstep: 1}) // up to 100 bins, but no smaller than 1 unit
      .bin({maxbins: 100}) 
      //.axis({format: 'd', titleAnchor: 'start'}), // integer format, left-aligned title
      .axis({titleAnchor: 'start'}), 
    vl.y().count().title(null) // no y-axis title
  );
  
  const hist1r = vl.layer(
      hist1.select(brush).encode(vl.color().value('lightgrey')),
      hist1.transform(vl.filter(brush))
    )
    .width(800).height(100)
    .repeat({row: Object.keys(attributes).filter(d => attributes[d] === "quantitative")});

  // 2 bars for non-quantitative data
  const hist2 = vl.markBar({tooltip: true}).encode(
    vl.x().field(vl.repeat('row'))
      .axis({titleAnchor: 'start'}), // left-aligned title
    vl.y().count().title(null) // no y-axis title
  );
  const hist2r = vl.layer(
      hist2.select(brush).encode(vl.color().value('lightgrey')),
      hist2.transform(vl.filter(brush))
    )
    .width(800).height(100)
    .repeat({row: Object.keys(attributes).filter(d => (attributes[d] !== "quantitative") && (cardinality[d] < 30) )});

  const plot = vl
    .data(processedData)
    .config({view: {stroke: null}}) // no outline
    .vconcat(hist1r, hist2r);
  
  return plot.render();
  // return html`<pre>${JSON.stringify(plot.toObject(), 0, 2)}</pre>`; // format JSON data
} 

然而,该代码至少有两个缺点:

  • 画笔选择始终是 selectInterval()。我希望它是定量属性的 selectInterval() ,否则是 selectMulti()

  • 什么是更有效的方法来完成这项工作?我为定量和其余属性创建了两个不同的图表,仅仅是因为后者不需要分箱。

任何帮助将不胜感激!

4

0 回答 0