【问题标题】:d3fc webgl candlesticks - setting fillStyle equivelant in webgld3fc webgl 烛台 - 在 webgl 中设置 fillStyle equivelant
【发布时间】:2020-04-07 21:48:05
【问题描述】:

我正在使用 d3fc+canvas 将烛台渲染为图表,并根据它是向上还是向下蜡烛来更改其填充颜色。系列生成器是这样的

const generator = fc.seriesCanvasCandlestick()
        .crossValue(d => d.date)
        .openValue(d => d.open)
        .highValue(d => d.high)
        .lowValue(d => d.low)
        .closeValue(d => d.close)
        .decorate((context, datum, index) => {

            context.fillStyle = datum.close > datum.open ? 'blue' : 'red'
        });

我现在正在尝试将其转换为 webGl 渲染(使用 seriesWebglCandlestick),但我不知道如何以相同的方式设置填充颜色。

如何转换我的装饰函数来为 webgl 烛台着色?

似乎我可以使用 context.context() 获取 Webgl 上下文,但在其上设置 fillStyle 并没有做任何事情。

我看到another stackoverflow answer建议:

renderer.setClearColor(0xcc3dca, 0.7)
renderer.clear()

但在 Webgl 上下文中似乎没有 setClearColor 函数(尽管我确实看到了 clear()

我也看到 clearColor() 需要 4 个参数,所以我尝试传递像 clearColor(197,197,197,0.7) 这样的 rgba 值,但也没有效果。

【问题讨论】:

    标签: d3fc


    【解决方案1】:

    现在这个功能已经发布了,代码应该是这样的-

    const fillColor = fc
        .webglFillColor()
        .data(data)
        .value(d => 
             d.close > d.open ? 
                 [0, 0, 1, 1] : [1, 0, 0, 1]
        );
    
    const series = fc
        .seriesWebglCandlestick()
        .xScale(xScale)
        .yScale(yScale)
        .context(gl)
        .crossValue((_, i) => i)
        .highValue(d => d.high)
        .lowValue(d => d.low)
        .openValue(d => d.open)
        .closeValue(d => d.close)
        .decorate(program => {
            fillColor(program);
        });
    

    注意如果没有填充,webglFillColor 将无效,例如为 ohlc。在这种情况下,您需要使用 webglStrokeColor 。

    原始答案如下。


    不幸的是,目前这对于 d3fc 中的 WebGL 系列来说并不容易,但我们确实希望 change shortly 做到这一点。

    就目前而言,这需要深入研究 d3fc-webgl 包的内部结构。我们目前不建议这样做(直到上述问题得到解决),因为组件的命名和确切功能可能会发生变化。

    但是,如果您非常想尝试一下,这里是当前版本所需的代码 -

    只有在您构建自己的库版本以从 packages/d3fc-webgl/index.js 导出 elementConstantAttributeBuilder 时,此代码才会运行

    const fillColorAttribute = fc
        .elementConstantAttributeBuilder()
        .size(4)
        .data(data)
        .value((data, element) => 
             data[element].close > data[element].open ? 
                 [0, 0, 1, 1] : [1, 0, 0, 1]
        );
    
    const series = fc
        .seriesWebglCandlestick()
        .xScale(xScale)
        .yScale(yScale)
        .context(gl)
        .crossValue((_, i) => i)
        .highValue(d => d.high)
        .lowValue(d => d.low)
        .openValue(d => d.open)
        .closeValue(d => d.close)
        .decorate(program => {
            program
                .vertexShader()
                .appendHeader('attribute vec4 aFillColor;')
                .appendHeader('varying vec4 vFillColor;')
                .appendBody('vFillColor = aFillColor;');
            program
                .fragmentShader()
                .appendHeader('varying vec4 vFillColor;')
                .appendBody('gl_FragColor = vFillColor;');
            program
                .buffers()
                .attribute('aFillColor', fillColorAttribute);
        });
    

    这会产生以下 -

    【讨论】:

    • 谢谢。 github.com/d3fc/d3fc/pull/1451 中的更改是否允许更新此答案?我已经在本地克隆了 webgl 分支,我正在尝试使用 fillColor.js 但遇到了问题。这个新代码是如何使用的?
    • 我是不是这样初始化:const fillColorWebgl = fillColor().value((data, element) => data[element].close > data[element].open ? [0, 0, 1, 1] : [1, 0, 0, 1]); 然后在webgl系列的decorate函数中传递程序:...decorate(program => fillColorWebgl(program))?我得到 programBuilder.context 没有定义。
    • 我会在发布代码时正确更新答案。它应该像这样使用 - ` const fillColor = fc.webglFillColor() .data(data) .value(d => d.close > d.open ? [0, 0, 1, 1] : [1, 0, 0, 1]);常量系列 = fc .seriesWebglCandlestick() .xScale(xScale) .yScale(yScale) .context(gl) .crossValue((_, i) => i) .highValue(d => d.high) .lowValue(d = > d.low) .openValue(d => d.open) .closeValue(d => d.close) .decorate(program => { fillColor(program); }); `
    • 既然更改已发布,您能否更新此答案。
    猜你喜欢
    • 1970-01-01
    • 2020-11-21
    • 2012-11-18
    • 2014-09-25
    • 2021-10-14
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多