Day26 D3js 浪漫复刻ExpertOption的养眼图表

D3js 浪漫复刻ExpertOption的养眼图表

用途

在以往实现d3图表时,多半是功能优先,可能在渐变处理以及外观样式比较不那麽苛求,因次复刻了一个之前接触过的二元期权的首页,试着美化d3图表

复刻对象ExpertOption

构成列表

  • 基本Scale
  • Path需要随着时间移动
  • Area需要随着时间移动
  • Circle(渐变)并需要随着最新值移动
  • 其他装饰

Scale

n为图表上会存在的点为数量,假定为40。因此整个资料长度最大值为40,也就是xScaledomain会从0-39(40个)

let xScale = d3.scaleLinear()
                .domain([0, n - 1])
                .range([0, width]);

let yScale = d3.scaleLinear()
                .domain([-200, 200])
                .range([height, 0])
                .nice();

Area

d3.curveCatmullRom.alpha(0.1)为线段弧度,让我们的图表看起来圆润一点。
y0 - y1为整个Area垂直的范围。

let area = d3.area()
    .x((d, i) => xScale(i))
    .y1(d => yScale(d))
    .y0(d => yScale(-200))
    .curve(d3.curveCatmullRom.alpha(0.1));

Line

d3.curveCatmullRom.alpha(0.1)为线段弧度,让我们的图表看起来圆润一点。

let line = d3.line()
              .x((d, i) => xScale(i))
              .y((d, i) => yScale(d))
              .curve(d3.curveCatmullRom.alpha(0.1));

defs

这是遮罩,用来让我们隐藏超出我们期待边界的部分。

使用方法:selection.attr("clip-path", "url(#clip)"),设定属性clip-pathurl(指定隐藏图层ID)

rootLayer.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height)

渐层色

渐变色是指向是Line的颜色,Area的颜色,因为是渐层变化,而且在svg元件上,我都是使用图层的方式盖上颜色。

此部分渐变色由於并没有动态因变数而改变,所以直接写在静态html上。

使用方法

HTML

<defs>
    <linearGradient id="lineColor">
    <stop offset="100%" stop-opacity="0.7" stop-color="#2D9FF8"></stop></linearGradient>
</defs>
<defs>
    <linearGradient id="areaColor" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0%" stop-opacity="0.7" stop-color="#315B90"></stop>
        <stop offset="50%" stop-color="#315B90" stop-opacity="0.4"></stop>
        <stop offset="100%" stop-color="#315B90" stop-opacity="0"></stop>
    </linearGradient>
</defs>

Javascript
透过url(#ID)指定要使用的图层ID

let lines = linesLayer
        .append('path')
        .datum(data)
        .attr('class', 'line')
        .attr('stroke-width', 5)
        .attr('d', line)
        .attr('stroke', 'url(#lineColor)')

let areas = linesLayer
        .append('path')
        .datum(data)
        .attr('class', 'area')
        .attr('d', area)
        .attr('fill', 'url(#areaColor)');

移动原理

移动原理其实就是透过transform="translate"进行移动,每一个间隔时间会往左侧移动一个单位,当移动到位置时,会重置位置。因此从外部看来,就像是一直往左侧移动。而也因此在重置时会绘制新的线段,造成看起来好像示意图一样,无限的往左设滑动,其实只是一直重新绘制线段外加往左侧移动。

部分程序码

以下tick触发时间为图层准备开始动作时。

function tick() {
  data.push(random()); // 推入一笔资料
  
  // 重新绘制线段
  lines
    .attr('d', line)
    .attr("transform", null);
  
  // 重新绘制区块
  areas
    .attr('d', area)
    .attr("transform", null);
  
  linesLayer
    .attr("transform", null) // 先将位移归零重置
    .transition()            // 设定渐变
    .duration(1500)          // 时间1.5s
    .ease(d3.easeLinear)     // 平滑移动
    .attr("transform", "translate(" + xScale(-1) + ",0)") // 渐变时间1.5s置`xScale(-1)`的位置
    .on('end', tick) // 结束时触发下一次`tick`,如此看起来会像是无限往左。
    
  data.shift();
}

其余装饰

其余装饰为title, html, css相关较不重要,至於会跟着最新值走的球,其实也只是跟着random出来的资料并使用yScale算出对应的位置,渐变时间设定与LinesLayer时间一样即可。并固定x在最後。

结论

找一个现成的图表仿制真的满有趣的,虽然不清楚ExpertOption以及这种透资方是到底是不是正当的,他们的图表功能做的真的挺完整的。

如果想详细了解复刻图表的Code请至Codepen

Codepen范例

参考

Mike Path Transitions
ExpertOption


<<:  [Day. 26] Codeigniter 页面

>>:  [Day27]jsES6语法-解构(下)

资安认知-电子邮件钓鱼

在社交工程的攻击中,我们最常见的也莫过於电子邮件钓鱼 电子邮件钓鱼也被列为主要进行社交工程演练的项目...

Day029-透过Vuex-实作简易部落格-打包你的专案吧!

Vue:还记得第10天时,我们才刚认识Vue CLI,但你还记得我的介面吗? 接着,我们试试看这个指...

[CSS] Flex/Grid Layout Modules, part 16

Media Query 我觉得已经讲到快烂掉了,搭配 Grid 说实在话也没有很不好做的地方。不过,...

Day 6 hook的前奏useEffect

useEffect 在class component时,分别有三个生命周期componentDidU...