折线图
<p>这段代码绘制了一个线形图,使用 D3.js 来创建和设置图表。以下是对代码的详细解释:</p>
<ol>
<li>
<p><strong>初始化和参数设置</strong></p>
<pre><code class="language-javascript">this.init(d3.select(svg));
const xPadding = 60;
const yPadding = 60;
const xExtent = d3.extent(data, item =&gt; item.x);
const yExtent = d3.extent(data, item =&gt; item.y);</code></pre>
<ul>
<li><code>this.init(d3.select(svg));</code>:初始化图表,选择传入的 <code>svg</code> 元素。</li>
<li><code>xPadding</code> 和 <code>yPadding</code>:图表的内边距,用于设置坐标轴和图表边缘的距离。</li>
<li><code>xExtent</code> 和 <code>yExtent</code>:数据中 x 和 y 值的范围。</li>
</ul>
</li>
<li>
<p><strong>清理和设置画布</strong></p>
<pre><code class="language-javascript">this.g.selectAll('.chartCtywc-g').remove();
const g = this.g.append('g').attr('class', 'chartCtywc-g');</code></pre>
<ul>
<li>清除之前可能存在的图表元素。</li>
<li>创建一个新的 <code>&lt;g&gt;</code> 元素,用于容纳图表内容。</li>
</ul>
</li>
<li>
<p><strong>设置比例尺</strong></p>
<pre><code class="language-javascript">const x = d3.scaleLinear()
.domain(xExtent)
.range([xPadding, width - xPadding]);
const y = d3.scaleLinear()
.domain(yExtent)
.range([height - yPadding, yPadding]);</code></pre>
<ul>
<li><code>x</code> 和 <code>y</code> 是线性比例尺,将数据值映射到图表的像素位置。</li>
</ul>
</li>
<li>
<p><strong>绘制坐标轴</strong></p>
<pre><code class="language-javascript">const axisBottom = d3.axisBottom(x);
const axisLeft = d3.axisLeft(y);
g.append('g')
.style('pointer-events', 'none')
.attr('class', 'axis-x').call(axisBottom)
.attr('font-size', 10)
.attr('transform', `translate(0,${height - yPadding})`);
g
.append('g')
.style('pointer-events', 'none')
.attr('class', 'axis-y').call(axisLeft)
.attr('font-size', 10)
.attr('transform', `translate(${xPadding},0)`);</code></pre>
<ul>
<li>使用 <code>d3.axisBottom</code> 和 <code>d3.axisLeft</code> 创建 x 轴和 y 轴。</li>
<li>将这些轴添加到 <code>&lt;g&gt;</code> 元素中,并设置变换属性来定位坐标轴。</li>
</ul>
</li>
<li>
<p><strong>绘制线条</strong></p>
<pre><code class="language-javascript">const line = d3.line()
.x(function (d) { return x(d.x); })
.y(function (d) { return y(d.y); });
g.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', '#fff')
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1.5)
.style('pointer-events', 'none')
.attr('d', line);</code></pre>
<ul>
<li>使用 <code>d3.line()</code> 创建线条生成器。</li>
<li>将数据绑定到 <code>&lt;path&gt;</code> 元素,并用 <code>line</code> 生成路径。</li>
<li>设置线条的样式,包括颜色、宽度和端点样式。</li>
</ul>
</li>
<li><strong>添加坐标轴标签</strong>
<pre><code class="language-javascript">g.append('text')
.attr('x', width - 80)
.attr('y', height - 20)
.attr('text-anchor', 'middle')
.attr('fill', '#fff')
.attr('font-size', 12)
.text(() =&gt; '位置(mm)');
g.append('text')
.attr('x', 60)
.attr('y', 40)
.attr('text-anchor', 'middle')
.attr('fill', '#fff')
.attr('font-size', 12)
.text(() =&gt; '数量(counts)');</code></pre>
<ul>
<li>向图表添加 x 轴和 y 轴的标签,分别是 "位置(mm)" 和 "数量(counts)"。</li>
</ul></li>
</ol>
<p>总体而言,这段代码通过设置比例尺、绘制坐标轴、绘制线条和添加标签来创建一个线形图,用于展示数据的变化趋势。
完整代码</p>
<pre><code class="language-javascript">
lineChartCtywc(data, svg, width, height) {
this.init(d3.select(svg));
const xPadding = 60;
const yPadding = 60;
const xExtent = d3.extent(data, item =&gt; item.x);
const yExtent = d3.extent(data, item =&gt; item.y);
// 移除之前可能存在的画布
this.g.selectAll('.chartCtywc-g').remove();
const g = this.g.append('g').attr('class', 'chartCtywc-g');
const x = d3.scaleLinear()
.domain(xExtent)
.range([xPadding, width - xPadding]);
const y = d3.scaleLinear()
.domain(yExtent)
.range([height - yPadding, yPadding]);
// 绘制坐标系
const axisBottom = d3.axisBottom(x);
const axisLeft = d3.axisLeft(y);
g.append('g')
.style('pointer-events', 'none')
.attr('class', 'axis-x').call(axisBottom)
.attr('font-size', 10)
.attr('transform', `translate(0,${height - yPadding})`);
// 添加y轴
g
.append('g')
.style('pointer-events', 'none')
.attr('class', 'axis-y').call(axisLeft)
.attr('font-size', 10)
.attr('transform', `translate(${xPadding},0)`);
const line = d3.line()
// .curve(d3.curveBasis) //开启贝塞尔曲线绘制
.x(function (d) {
return x(d.x);
})
.y(function (d) {
return y(d.y);
});
g.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', '#fff')
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1.5)
.style('pointer-events', 'none')
.attr('d', line);
g.append('text')
.attr('x', width - 80)
.attr('y', height - 20)
.attr('dx', 0)
.attr('dy', 0)
.attr('text-anchor', 'middle')
.attr('fill', '#fff')
.attr('font-size', 12)
.text(() =&gt; '位置(mm)');
g.append('text')
.attr('x', 60)
.attr('y', 40)
// .attr('dx', -20)
.attr('dy', 0)
.attr('text-anchor', 'middle')
.attr('fill', '#fff')
.attr('font-size', 12)
.text(() =&gt; '数量(counts)');
}</code></pre>