vtk.js

vtk.js


绘制散点图

<h3>函数定义和输入参数</h3> <pre><code>scattergram(data, imgWidth, imgHeight) {</code></pre> <p>scattergram 函数接受三个参数:</p> <ul> <li>data:包含散点图数据的对象。</li> <li>imgWidth 和 imgHeight:图像的宽度和高度,用于设置绘图区域的尺寸。</li> </ul> <h3>初始化变量和数据处理</h3> <pre><code>const canvasWidth = this.vm.imageWidth; const canvasHeight = this.vm.imageHeight; const location = data.data.vector; const type_vec = data.data.type_vec || []; const points = []; let umin = location[0] || 0; let umax = location[0] || 0; let vmin = location[1] || 0; let vmax = location[1] || 0; let count = 0;</code></pre> <ul> <li>canvasWidth 和 canvasHeight:从 this.vm 对象中获取图像的宽度和高度。</li> <li>location:从 data.data.vector 中获取包含点坐标的数组。</li> <li>type_vec:从 data.data.type_vec 中获取点的类型数组,默认为空数组。</li> <li>points:存储筛选后的点数据。</li> <li>umin, umax, vmin, vmax:用于记录数据中 u 和 v 坐标的最小值和最大值。</li> <li>count:用于跟踪当前点的索引。</li> </ul> <h3>处理数据点</h3> <pre><code>for (let index = 0; index &amp;lt; location.length; index += 3) { const u = location[index]; const v = location[index + 1]; const w = location[index + 2]; if (isNaN(u) || isNaN(v) || isNaN(w)) { count++; continue; } if (type_vec) { if (type_vec[count] &amp;lt;= 0) { count++; continue; } } count++; if (u &amp;gt; umax) umax = u; if (u &amp;lt; umin) umin = u; if (v &amp;gt; vmax) vmax = v; if (v &amp;lt; vmin) vmin = v; points.push([u, v, w]); }</code></pre> <ul> <li>遍历 location 数组中的每个点(每三个值代表一个点的 u, v, w 坐标)。</li> <li>如果点的坐标值不是数字,则跳过该点。</li> <li>如果 type_vec 存在,并且对应的类型值小于等于0,则跳过该点。</li> <li>更新 u 和 v 的最小值和最大值。</li> <li>将有效的点([u, v, w])添加到 points 数组中。</li> </ul> <h3>设置比例尺</h3> <pre><code>const x = this.xScale = d3.scaleLinear() .domain([umin, umax]) .range([30, canvasWidth - 30]); const y = this.yScale = d3.scaleLinear() .domain([vmin, vmax]) .range([30, canvasHeight - 30]);</code></pre> <ul> <li>使用 D3 的 scaleLinear 方法创建 x 轴和 y 轴的线性比例尺。</li> <li>domain 定义了数据的范围(最小值到最大值)。</li> <li>range 定义了绘图区域的范围(30 到 canvas 的宽度或高度减去 30)。</li> </ul> <h3>绘制点</h3> <pre><code>this.g.append('g') .attr('class', 'dot') .attr('fill-opacity', 1) .style('pointer-events', 'none') .selectAll('circle') .data(points) .enter().append('circle') .attr('u', d =&amp;gt; d[0]) .attr('v', d =&amp;gt; d[1]) .attr('w', d =&amp;gt; d[2]) .attr('transform', function (d) { return `translate(${x(d[0])},${y(d[1])})`; }) .attr('fill', 'red') .attr('r', () =&amp;gt; { if (points.length &amp;gt; 1000) { return 0.5; } else if (points.length &amp;lt;= 1000 &amp;amp;&amp;amp; points.length &amp;gt; 500) { return 1; } else if (points.length &amp;lt;= 500 &amp;amp;&amp;amp; points.length &amp;gt; 100) { return 1.5; } else { return 2; } });</code></pre> <ul> <li>向 this.g 元素中添加一个新的 &lt;g&gt; 元素用于容纳点。</li> <li>选择所有 &lt;circle&gt; 元素,绑定 points 数据,并对每个点添加一个 &lt;circle&gt; 元素。</li> <li>设置每个圆的位置(通过 transform 属性)。</li> <li>根据点的数量设置不同的圆半径。</li> </ul> <h3>添加坐标轴</h3> <pre><code>const axisBottom = d3.axisBottom(x); const axisLeft = d3.axisLeft(y); // 添加x轴 const axixXg = this.g .append('g') .style('pointer-events', 'none') .attr('class', 'axis-x').call(axisBottom) .attr('font-size', 12) .attr('transform', `translate(0,${canvasHeight - 30})`) const axixYg = this.g .append('g') .style('pointer-events', 'none') .attr('class', 'axis-y').call(axisLeft) .attr('font-size', 12) .attr('transform', 'translate(30,0)')</code></pre> <ul> <li>使用 D3 的 axisBottom 和 axisLeft 方法创建 x 轴和 y 轴。</li> <li>将这些轴添加到 this.g 元素中,并设置适当的变换属性来定位轴。</li> </ul> <h3>添加坐标轴标签</h3> <pre><code>axixXg.append('text') .attr('x', canvasWidth - 80) .attr('y', 25) .attr('dx', 40) .attr('dy', 10) .attr('text-anchor', 'middle') .attr('fill', '#fff') .attr('font-size', 12) .text('U值'); axixYg.append('text') .attr('x', 0) .attr('y', 40) .attr('dx', -20) .attr('dy', -20) .attr('text-anchor', 'middle') .attr('fill', '#fff') .attr('font-size', 12) .text('V值');</code></pre> <p>向 x 轴和 y 轴添加文本标签,分别为 &quot;U值&quot; 和 &quot;V值&quot;。</p> <p>这段代码用于创建一个散点图,处理数据、设置坐标轴和比例尺,并在图中绘制点。</p> <p>完整代码:</p> <pre><code class="language-javascript"> scattergram(data, imgWdith, imgHeight) { const canvasWidth = this.vm.imageWidth; const canvasHeight = this.vm.imageHeight; const location = data.data.vector; const type_vec = data.data.type_vec || []; const points = []; let umin = location[0] || 0; let umax = location[0] || 0; let vmin = location[1] || 0; let vmax = location[1] || 0; let count = 0; for (let index = 0; index &amp;lt; location.length; index += 3) { const u = location[index]; const v = location[index + 1]; const w = location[index + 2]; if (isNaN(u) || isNaN(v) || isNaN(w)) { count++; continue; } if (type_vec) { if (type_vec[count] &amp;lt;= 0) { count++; continue; } } count++; if (u &amp;gt; umax) umax = u; if (u &amp;lt; umin) umin = u; if (v &amp;gt; vmax) vmax = v; if (v &amp;lt; vmin) vmin = v; points.push([u, v, w]); } this.allPoints = points; const x = this.xScale = d3.scaleLinear() .domain([umin, umax]) .range([30, canvasWidth - 30]); const y = this.yScale = d3.scaleLinear() .domain([vmin, vmax]) .range([30, canvasHeight - 30]); this.g.append('g') .attr('class', 'dot') .attr('fill-opacity', 1) .style('pointer-events', 'none') .selectAll('circle') .data(points) .enter().append('circle') .attr('u', d =&amp;gt; d[0]) .attr('v', d =&amp;gt; d[1]) .attr('w', d =&amp;gt; d[2]) .attr('transform', function (d) { return `translate(${x(d[0])},${y(d[1])})`; }) .attr('fill', 'red') .attr('r', () =&amp;gt; { if (points.length &amp;gt; 1000) { return 0.5; } else if (points.length &amp;lt;= 1000 &amp;amp;&amp;amp; points.length &amp;gt; 500) { return 1; } else if (points.length &amp;lt;= 500 &amp;amp;&amp;amp; points.length &amp;gt; 100) { return 1.5; } else { return 2; } }); const axisBottom = d3.axisBottom(x); const axisLeft = d3.axisLeft(y); // 添加x轴 const axixXg = this.g .append('g') .style('pointer-events', 'none') .attr('class', 'axis-x').call(axisBottom) .attr('font-size', 12) .attr('transform', `translate(0,${canvasHeight - 30})`) const axixYg = this.g .append('g') .style('pointer-events', 'none') .attr('class', 'axis-y').call(axisLeft) .attr('font-size', 12) .attr('transform', 'translate(30,0)') axixXg.append('text') .attr('x', canvasWidth - 80) .attr('y', 25) .attr('dx', 40) .attr('dy', 10) .attr('text-anchor', 'middle') .attr('fill', '#fff') .attr('font-size', 12) .text('U值'); axixYg.append('text') .attr('x', 0) .attr('y', 40) .attr('dx', -20) .attr('dy', -20) .attr('text-anchor', 'middle') .attr('fill', '#fff') .attr('font-size', 12) .text('V值'); }</code></pre>

页面列表

ITEM_HTML