d3fc:将不同的数据传递给渲染方法

问题描述

尝试改编this示例。略有不同:我有更多的WebGL数据,因此,根本不想将其传递给SVG渲染器。 SVG渲染器应该只获取一个数据点,但是随着用户移动鼠标,它会不断变化。

是否有可能具有基本上充当结点并将两个完全不同的数组传递到svgPlotArea()webglPlotArea()中的每个数组的切换功能

一个简化的原始代码段,一个图和两个渲染功能

const rand = d3.randomInt(0,100);

const data = d3.range(100).map(d => ({
  x: rand(),y: rand()
}));

data[50].hover = true;

let xScale = d3.scaleLinear()
  .domain([0,100])
  .range([0,100]);

let yScale = d3.scaleLinear()
  .domain([0,100]);

let webglSeries = fc.seriesWebglPoint()
  .crossValue(d => d.x)
  .mainValue(d => d.y)
  .type(d3.symbolCircle)
  .defined(() => true)
  .size(() => 100)
  .equals((prevData) => prevData.length);

let svgSeries = fc.seriesSvgPoint()
  .crossValue(d => d.x)
  .mainValue(d => d.y)
  .size(() => 300)
  .type(d3.symbolStar)
  .defined((d) => d.hover);

let chart = fc.chartCartesian(xScale,yScale)
  .webglPlotArea(webglSeries)
  .svgPlotArea(svgSeries);


function render() {
  d3.select("div")
    .datum(data)
    .call(chart);
}

render();
div {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
}
<script src="https://unpkg.com/d3"></script>
<script src="https://unpkg.com/d3fc"></script>


<div>
</div>

一个肮脏的骇客代码段,彼此之间有两个独立的图并分别提供数据:

const rand = d3.randomInt(0,100);

const big_data = d3.range(100).map(d => ({
  x: rand(),y: rand()
}));

const hover_data = [{
  x: 27,y: 11
},];

let xScale = d3.scaleLinear()
  .domain([0,100]);

let webglSeries = fc.seriesWebglPoint()
  .crossValue(d => d.x)
  .mainValue(d => d.y)
  .type(d3.symbolCircle)
  .defined(() => true)
  .size(() => 100)
  .equals((prevData) => prevData.length);

let svgSeries = fc.seriesSvgPoint()
  .crossValue(d => d.x)
  .mainValue(d => d.y)
  .size(() => 300)
  .type(d3.symbolStar)
  .defined(() => true);

let glchart = fc.chartCartesian(xScale,yScale)
  .webglPlotArea(webglSeries);

let svgchart = fc.chartCartesian(xScale,yScale)
  .svgPlotArea(svgSeries);

function render() {
  d3.select("#gl")
    .datum(big_data)
    .call(glchart);

  d3.select("#svg")
    .datum(hover_data)
    .call(svgchart);
}

render();
div {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
}
<script src="https://unpkg.com/d3"></script>
<script src="https://unpkg.com/d3fc"></script>


<div>
  <div id="gl">
  </div>
  <div id="svg">
  </div>
</div>

有没有更好的方法,例如下面的伪代码

const chart = d3fc.chartCartesian(xScale,yScale)
                  .svgPlotArea(svgSeries)
                  .webglPlotArea(webglSeries)

d3.select( "div" )
  .datum( function() { return whichRenderer ? data1 : data2 } )
  .call(chart);

解决方法

使用fc.seriesSvgMulti()似乎很有可能,请参见代码段。在控制台中,svgPlotArea的define()函数仅处理一个节点

let rand = d3.randomInt(0,100);

let data = d3.range(100).map(d => ({
    x: rand(),y: rand()
}));

let xScale = d3.scaleLinear()
               .domain([0,100])
               .range([0,100]);

let yScale = d3.scaleLinear()
               .domain([0,100]);

let webglSeries = fc.seriesWebglPoint()
                 .crossValue(d => d.x)
                 .mainValue(d => d.y)
                 .type(d3.symbolCircle)
                 .defined( () => true )
                 .size( () => 100 )
                 .equals( (prevData) => prevData.length );

let svgSeries = fc.seriesSvgPoint()
                 .crossValue(d => d.x)
                 .mainValue(d => d.y)
                 .size( () => 300 )
                 .type(d3.symbolStar)
                 .defined( (d) => { console.log("node check"); return true } );

let multi = fc.seriesSvgMulti()
                .series([svgSeries])
                 .mapping((data,index,series) => {
                     switch (series[index]) {
                         case svgSeries:
                             return getSingleNode();
                     }
                 });

let chart = fc.chartCartesian(xScale,yScale)
    .webglPlotArea(webglSeries)
    .svgPlotArea(multi);

function getSingleNode() {
  return [data[rand()]]
}

function render() {
  d3.select( "div" )
    .datum( data )
    .call(chart);
}

render();
div {
  position: absolute;
  width: 100%;
  height: 70%;
}
<script src="https://unpkg.com/d3"></script>
<script src="https://unpkg.com/d3fc"></script>

<div>
</div>