d3js精通教程

    科技2022-08-02  106

    d3js精通教程

    In the last article we learned about fundamentals of D3js such as selections, DOM Manipulation, SVG, Scales and data binding. If you are getting started with D3js, I highly recommend reading that article first and then come back here.

    在上一篇文章中,我们了解了D3js的基础知识,例如选择,DOM操作,SVG,Scales和数据绑定。 如果您开始使用D3js,我强烈建议您先阅读该文章 ,然后再回到这里。

    Lets dive into the world of Interactivity, Data Manipulation and Layouts in this article.

    在本文中,我们将深入探讨“ 交互性” ,“ 数据处理和布局 ”领域。

    事件处理 (Event Handling)

    Events can be attached by calling .on(event, function) on selection element and by passing the type of listener.

    可以通过在选择元素上调用.on(event, function)并传递侦听器的类型来附加.on(event, function) 。

    Lets start with the most basic interactive functionalities.

    让我们从最基本的交互功能开始。

    演示地址

    In the above example, click on js tab. See what are all the event handlers attached on the circles. Reload page and open console by pressing F12 and click on “Run Pen”.circles.on(‘mouseover’, console.log) this console logs all the parameters passed to callback functions. circles.on(‘mouseover’, (event, data)=> {}) 1st Event details, 2nd bond Data. This event is used is get the current event details which can used for variety of things like drag and drop and zoom. Alternatively, you can directly access event in js like this circles.on(‘click’, () => console.log(“Event”, event)) circles.on(‘dblclick’, ondblClick) : On double click event, here in the example we passed a function which turns the element “red”.circles.on(‘wheel’, (d, i, n) => console.log(“weeeee”, i)) : On scroll event, which is very handy for user friendly zooming event and last example ondrag event which is bit different where we have to call d3.drag() function on the element. Which has its on events like start, drag, end.

    在上面的示例中,单击js选项卡。 查看圆上附加的所有事件处理程序。 重新加载页面并按F12打开控制台,然后单击“运行笔”。 circles.on('mouseover', console.log)此控制台记录传递给回调函数的所有参数。 circles.on('mouseover', (event, data)=> {})第一事件详细信息,第二债券数据。 使用此event是获取当前事件的详细信息,该事件的详细信息可用于拖放和缩放之类的各种操作。 另外,您也可以直接在js中访问event ,例如circles.on('click', () => console.log(“Event”, event)) circles.on('dblclick', ondblClick) :发生双击事件时,在此示例中,我们传递了一个将元素变为“红色”的函数。 circles.on('wheel', (d, i, n) => console.log(“weeeee”, i)) :滚动事件,对于用户友好的缩放事件和最后一个示例ondrag事件非常方便不同之处在于我们必须在元素上调用d3.drag()函数。 它具有on事件,例如start , drag , end 。

    circles.call(d3.drag().on(“start”, console.log) .on(“drag”, onDrag) .on(“end”, console.log))

    In onDrag function we select the element and change its cx property with x property from its event .

    在onDrag函数中,我们选择元素并从其event x属性更改其cx属性。

    function onDrag(d,i,n) { d3.select(this).attr(“cx”, event.x) }

    Remember only traditional function passes context in this while arrow function refers to its relative parent context. If its an arrow function it should look like.

    请记住,只有传统function会在this传递上下文,而箭头函数是指其相对父上下文。 如果它具有箭头功能,则应该看起来像。

    const onDrag = (d,i,n) => { d3.select(n[i]).attr(“cx”, event.x) }

    Here is the list of most used mouse events.

    这是最常用的鼠标事件的列表。

    click: Mouse click on the element.

    click :鼠标单击元素。

    dblclick: Mouse double click on the element.

    dblclick :鼠标双击元素。

    contextmenu: Mouse right click on the element.

    contextmenu :鼠标右键单击元素。

    mouseenter: Mouse enters the element.

    mouseenter :鼠标进入元素。

    mouseleave: Mouse leaves the element.

    mouseleave :鼠标离开元素。

    mousemove: Mouse movement over the element.

    mousemove :鼠标在元素上移动。

    mouseout: Mouse leaves the element or any of its children.

    mouseout :鼠标离开该元素或其任何子元素。

    mouseover: Mouse enters the element or any of its children.

    mouseover :鼠标进入元素或其任何子元素。

    for Touch interface read Here

    对于触摸界面,请点击此处

    Check more about it here.

    在这里查看更多信息。

    There are more D3js provided interactive features

    D3js提供了更多的交互式功能

    d3.drag: Drag event with mouse.

    d3.drag :用鼠标拖动事件。

    d3.zoom: Zoom event with mouse wheel.

    d3.zoom :使用鼠标滚轮缩放事件。

    d3.brush: Can be used for select area or zooming.

    d3.brush :可用于选择区域或缩放。

    d3.force : To simulate gravitational animation

    d3.force :模拟重力动画

    Follow me Sai Kiran Goud to learn about these interactive visualization developments.

    跟随我Sai Kiran Goud了解这些交互式可视化技术的发展。

    工具提示示例: (Tooltip Example:)

    https://codepen.io/krngd2/pen/YzqYNRe

    https://codepen.io/krngd2/pen/YzqYNRe

    数据处理 (Data Manipulation)

    D3js comes with variety of data manipulation function which comes in pretty handy while dealing with any kind off data.

    D3js带有各种数据处理功能,在处理任何类型的数据时都非常方便。

    Take some example data of Covid-19 cases in India.

    以印度的Covid-19病例为例。

    [{“dailyconfirmed”: “78168”,”dailydeceased”: “892”,”dailyrecovered”: “62145”,”date”: “01 September “,”totalconfirmed”: “3766121”,”totaldeceased”: “66337”,”totalrecovered”: “2899515”},..................{“dailyconfirmed”: “90600”,”dailydeceased”: “916”,”dailyrecovered”: “73161”,”date”: “05 September “,”totalconfirmed”: “4110852”,”totaldeceased”: “70095”,”totalrecovered”: “3177666”}]

    This is an array of Objects, If we want to get the maximum dailyconfirmed cases, you have d3.max(data, accessor) , example

    这是一个对象数组,如果要获取最大的dailyconfirmed病例,则可以使用d3.max(data, accessor) ,例如

    d3.max(data,(p)=> p["dailyconfirmed"] ) // returns "90600"

    Similarly we have

    同样,我们有

    最高 (Max)

    d3.max(iterable[, accessor]) : returns max valued3.maxIndex(iterable[, accessor]) : returns Index of max valued3.greatest(iterable[, comparator]) : returns object of max index

    d3.max( iterable [, accessor ]) :返回最大值d3.maxIndex( iterable [, accessor ]) :返回最大值的索引d3.greatest( iterable [, comparator ]) :返回最大索引的对象

    (Min)

    d3.min(iterable[, accessor]) : returns min valued3.minIndex(iterable[, accessor]) : returns Index of min valued3.least(iterable[, comparator]) : returns object of min index

    d3.min( iterable [, accessor ]) :返回最小值d3.minIndex( iterable [, accessor ]) :返回最小值d3.least( iterable [, comparator ])的索引:返回min索引的对象

    其他 (Others)

    d3.sum(iterable[, accessor]) : returns Sumd3.extent(iterable) : returns [min, max] combined in an arrayd3.mean(iterable[, accessor]) : returns mean valued3.median(iterable[, accessor]) : returns median value

    d3.sum( iterable [, accessor ]) :返回总和d3.extent( iterable) :返回[min,max]组合成一个数组 d3.mean( iterable [, accessor ]) : 返回平均值 d3.median( iterable [, accessor ]) : 返回中值

    转型 (Transformation)

    Here the interesting part begins. Transformation methods comes very handy when you want to modify your data to desired format. Lets learn about most used transformation methods.Taken above data as example.

    从有趣的部分开始。 当您想将数据修改为所需格式时,转换方法非常方便。 让我们了解最常用的转换方法。以上述数据为例。

    d3.group(data, d => d["date"])

    output

    输出

    This returns a Map with key of date and value of the rest of the values. This comes handy when you want to access values by passing the date and using Map instead Object for such data improves performance too. You can pass more callback functions to get more nested data. Convert to Array using Array.from(mapData) .

    这将返回一个地图 带有日期的键和其余值的值。 当您想通过传递日期并使用Map代替Object访问此类数据来访问值时,这也很方便。 您可以传递更多的回调函数以获取更多的嵌套数据。 使用转换为数组 Array.from(mapData) 。

    Note keys should be unique, otherwise they will be over ridden. If you want an error to be thrown, use d3.index(iterable, keyAccessory) with similar functionality. If you want to customized output of values array use d3.rollup(iterable, reduce, …keys) // Learn about .reduce() here You can check more about it Here.

    注意键应该是唯一的,否则它们将被覆盖。 如果要引发错误,请使用 d3.index(iterable, keyAccessory) 具有相似的功能。 如果你想要将其值阵列中使用的定制输出d3.rollup( iterable , reduce , …keys ) // Learn about .reduce() here你可以查看更多关于它在这里 。

    d3.range([start, ]stop[, step]) // generates array of valuesd3.merge([[1], [2, 3]]) //returns [1, 2, 3]d3.pairs([1, 2, 3, 4]); // returns [[1, 2], [2, 3], [3, 4]]d3.shuffle(array[, start[, stop]]) // shuffles the array

    d3.range([ start , ] stop [, step ]) // generates array of valuesd3.merge([[1], [2, 3]]) //returns [1, 2, 3]d3.pairs([1, 2, 3, 4]); // returns [[1, 2], [2, 3], [3, 4]]d3.shuffle( array [, start [, stop ]]) // shuffles the array

    d3.ticks(start, stop, count)// returns array of equal interval rounded values// exampled3.ticks(1, 10, 5)// returns

    Here I only listed out mostly used methods according my experience. You can read about all of them here Statistics, Search, Transform

    在这里,我仅根据我的经验列出最常用的方法。 您可以在此处阅读所有内容的统计信息 , 搜索 , 转换

    版面 (Layouts)

    There are so many types of visualization. D3 gives us some handy inbuilt visualizations like Packed Circles, TreeMap, Network Graph etc.

    可视化类型很多。 D3为我们提供了一些方便的内置可视化效果,例如填充圆圈,TreeMap,网络图等。

    In-order to develop them you need to understand an important data manipulation method to produce Hierarchical Data.

    为了开发它们,您需要了解一种重要的数据处理方法以生成分层数据。

    Hierarchical Data

    分层数据

    Just like how Scales takes data and outputs the positional points, Hierarchical functions, takes hierarchical data and adds positional x,y and other points such that it can produces certain layout. We need to prepare some hierarchical data first. For that we have d3.stratify() .Lets say we have data something like

    就像Scales如何获取数据并输出位置点一样,Herarchical函数也可以获取层次数据并添加位置x,y和其他点,从而可以生成特定的布局。 我们需要首先准备一些分层数据。 为此,我们有d3.stratify()让我们说我们有类似的数据

    const data = [ {"name": "Eve", "parent": ""}, {"name": "Cain", "parent": "Eve"}, {"name": "Seth", "parent": "Eve"}, {"name": "Enos", "parent": "Seth"}, {"name": "Noam", "parent": "Seth"}, {"name": "Abel", "parent": "Eve"}, {"name": "Awan", "parent": "Eve"}, {"name": "Enoch", "parent": "Awan"}, {"name": "Azura", "parent": "Eve"}]

    To convert this into hierarchical data we need pass this data to d3.stratify()

    要将其转换为分层数据,我们需要将此数据传递给d3.stratify()

    const hierarchicalDataGenrator = d3.stratify() .id(d => d.name) .parentId(d => d.parent)hierarchicalDataGenrator(data) Output 输出量

    Above is output, we get Hierarchical data object with we can get hierarchicalDataGenrator.ancestors() , hierarchicalDataGenrator.descendants() , hierarchicalDataGenrator.leaves() . Typically you don’t need to use these directly. Let build some visualizations now.

    以上是输出,我们得到了Hierarchical数据对象,并获得了hierarchicalDataGenrator.ancestors() , hierarchicalDataGenrator.descendants() , hierarchicalDataGenrator.leaves() 。 通常,您不需要直接使用它们。 现在建立一些可视化。

    实心圆 (Packed Circles)

    https://covidwithd3js.kiran.dev/worldbubble/ https://covidwithd3js.kiran.dev/worldbubble/

    Lets take a simple same data as above but add an extra point value. Value is the percentage of circle occupation under its parent. Lets keep everything 1. Like this {“name”: “Eve”, “parent”: “”, value: 1} .

    让我们采用与上述相同的简单数据,但添加一个额外的点值。 值是其父项下的圈子职业百分比。 让我们保留所有内容1.像这样{“name”: “Eve”, “parent”: “”, value: 1} 。

    Make Data Hierarchical

    使数据分层

    const hDataGenerator = d3.stratify() .id(d=>d.name) .parentId(d => d.parent)const hData = hDataGenerator(data)

    2. Sum the value

    2.求和

    hData.sum(d => d.value)console.log(

    You can see extra value key added. That’s the sum of all its children values.

    您会看到添加了value键。 那是所有子代价值的总和。

    3. Prepare the pack layout

    3.准备包装布局

    const packLayout = d3.pack() .size([400, 400]);packLayout(hData)

    4. Use it to create layout

    4.用它来创建布局

    const nodes = d3.select('svg') .append('g') .selectAll('circle') .data(hData.descendants()) .enter() .append("g")nodes.append('circle') .attr('cx', (d) => d.x) .attr('cy', (d) => d.y) .attr('r', (d) => d.r) .style("stroke", "black") .style("fill", "none")nodes.append('text') .attr('y', (d) => d.y - d.r + 16) .attr('x', (d) => d.x) .text(d => d.data.name)

    Output

    输出量

    树状图 (TreeMap)

    Almost everything same as above but instead of d3.pack() we use d3.tree()

    几乎一切都与上面相同,但不是d3.pack()我们使用d3.tree()

    Prepare Layout

    准备布局

    const treeLayout = d3.tree().size([400, 400]);treeLayout(hData)

    Create

    创造

    const svg = d3.select('svg')//circlessvg.append('g') .selectAll('circle.node') .data(hData.descendants()) .enter() .append('circle') .classed('node', true) .attr('cx', (d) => d.x) .attr('cy', (d) => d.y) .attr('r', 4);// Linkssvg.append("g") .selectAll('line.link') .data(hData.links()) .enter() .append('line') .attr('x1', (d) => d.source.x) .attr('y1', (d) => d.source.y) .attr('x2', (d) => d.target.x) .attr('y2', (d) => d.target.y) .style('stroke', 'black')

    Output

    输出量

    Learn More about Hierarchy here

    在此处了解有关层次结构的更多信息

    I am hoping by now you got pretty good idea about how to play around with D3js. I know we haven't built any exciting chart in these series. In my next article we will build Racing Bar chart. So follow me for the more exciting stuff.

    我希望到目前为止,您对如何使用D3js有一个很好的了解。 我知道在这些系列中我们还没有建立任何令人兴奋的图表。 在我的下一篇文章中,我们将构建赛车条形图。 因此,请跟随我获得更精彩的内容。

    翻译自: https://medium.com/analytics-vidhya/d3js-basic-to-mastery-part-2-mastery-680db40f2ec5

    d3js精通教程

    Processed: 0.017, SQL: 8