私はd3 v4(4.12.0)を使用しています。d3 v4で無限水平軸を作成
私はSVGコンテナを持っています。このコンテナには、マウスでパンすることに対応する単純な水平軸(x軸、リニアスケール)が描画されています。
"無限"または "無限"の横軸をシミュレートしたいと思います。
これは、非常に大きなデータセットの小さな部分だけをロードしてレンダリングし、この大きなセットの要素の非常に小さなサブセットを示す軸だけを描画することを意味します。
私は、オブジェクトの大きな配列から10データポイントを示す横軸を持っていると言います。私はoffset
パラメータを保持しています。このパラメータは0から始まり、この配列の最初の10点を表示します。
マイ手順:
私はに軸をスクロールすると十分11日以降のデータポイントを表示するには、その後、私は左:
更新
offset
パラメータが反映させるためにどのように多くのユニットI新しいオフセット値再オフに基づいて、
更新X軸スケールを翻訳しました私の試みは、最大動作します
軸(scroller_element_width
)で1つの単位を表す画素数で軸を含むグループ要素を翻訳
(x_scale
)更新規模の範囲で軸ラベルを描きますステップ3に進みます。このプロセスは、ステップ4で失敗したように見えます。軸の最終的な移動は決して起こらないという点です。
軸全体が左に移動し、新しいラベルがありますが、更新されたラベルでは右に移動しません。基本的にはページ外になります。
私はd3の専門家にこのステップが失敗している理由とこれを解決するために何ができるかをここで質問したいと思います。
renderScroller() {
console.log("renderScroller called");
if ((this.state.scrollerWidth == 0) || (this.state.scrollerHeight == 0)) return;
const self = this;
const scroller = this.scrollerContainer;
const scroller_content = this.scrollerContent;
const scroller_width = this.state.scrollerWidth;
const scroller_height = this.state.scrollerHeight;
var offset = 0,
limit = 10,
current_index = 10;
var min_translate_x = 0,
max_translate_x;
var scroller_data = Constants.test_data.slice(offset, limit);
var x_extent = d3.extent(scroller_data, function(d) { return d.window; });
var y_extent = [0, d3.max(scroller_data, function(d) { return d.total; })];
var x_scale = d3.scaleLinear();
var y_scale = d3.scaleLinear();
var x_axis_call = d3.axisTop();
x_scale.domain(x_extent).range([0, scroller_width]);
y_scale.domain(y_extent).range([scroller_height, 0]);
x_axis_call.scale(x_scale);
d3.select(scroller_content)
.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + [0, scroller_height] + ")")
.call(x_axis_call);
var scroller_element_width = parseFloat(scroller_width/(x_scale.domain()[1] - x_scale.domain()[0]));
var pan = d3.zoom()
.on("zoom", function() {
var t = parseSvg(d3.select(scroller_content).attr("transform"));
var x_offset = parseFloat((t.translateX + d3.event.transform.x)/scroller_element_width);
//
// lock scale and prevent y-axis pan
//
d3.event.transform.y = 0;
if (d3.event.transform.k == 1) {
d3.event.transform.x = (x_offset > 0) ? 0 : d3.event.transform.x;
}
else {
d3.event.transform.k = 1;
d3.event.transform.x = t.translateX;
}
d3.select(scroller_content).attr("transform", d3.event.transform);
t = parseSvg(d3.select(scroller_content).attr("transform"));
x_offset = parseFloat(t.translateX/scroller_element_width);
var test_offset = Math.abs(parseInt(x_offset));
if (test_offset != offset) {
scroller_data = updateScrollerData(test_offset);
x_extent = d3.extent(scroller_data, function(d) { return d.window; });
y_extent = [0, d3.max(scroller_data, function(d) { return d.total; })];
x_scale.domain(x_extent).range([0, scroller_width]);
y_scale.domain(y_extent).range([scroller_height, 0]);
x_axis_call.scale(x_scale);
//
// update axis labels
//
d3.select(scroller_content)
.selectAll(".x.axis")
.call(x_axis_call);
//
// shift the axis backwards to simulate an endless horizontal axis
//
var pre_shift = parseSvg(d3.select(scroller_content).attr("transform"));
console.log("pre_shift", pre_shift.translateX);
console.log("scroller_element_width", scroller_element_width);
var expected_post_shift = pre_shift.translateX + scroller_element_width;
console.log("(expected) post_shift", expected_post_shift);
d3.zoom().translateBy(d3.select(scroller_content), expected_post_shift, 0);
//
// observed and expected translate values do not match!
//
var post_shift = parseSvg(d3.select(scroller_content).attr("transform"));
console.log("(observed) post_shift", post_shift.translateX);
}
});
d3.select(scroller).call(pan);
max_translate_x = this.state.scrollerWidth - x_scale(x_extent[1]);
d3.zoom().translateBy(d3.select(scroller), max_translate_x, 0);
// fetch test data
function updateScrollerData(updated_offset) {
offset = updated_offset;
return Constants.test_data.slice(updated_offset - 1, updated_offset + limit - 1);
}
}
これが反応コンポーネント内の関数である:ここ
は、軸を描画し、ズームイベントをフックする機能です。原料に反応それほど関係ありませんが、ここではそのコンポーネントのrender()
機能で、親SVGと子グループの要素を表示する:
render() {
return (
<svg
className="scroller"
ref={(scroller) => { this.scrollerContainer = scroller; }}
width={this.state.scrollerWidth}
height={this.state.scrollerHeight}>
<g
className="scroller-content"
ref={(scrollerContent) => { this.scrollerContent = scrollerContent; }}
/>
</svg>
);
}
示すように、scrollerContainer
refは族元素が含まれているSVGありますscrollerContent
。このscrollerContent
は、水平軸を含むものです。
x軸をパンまたはスクロールすると、変換はscrollerContent
に適用されます。
変換パラメータを取得するには、私はd3-interpolate
のparseSvg
ヘルパーメソッドを使用しています。ES6経由:完全性については
import * as d3 from 'd3';
import { parseSvg } from "d3-interpolate/src/transform/parse";
、ここでのテストデータの抜粋です:
export const test_data = [
{
"total": 29.86,
"signal": [
4.842,
1.608,
1.837,
3.052,
1.677,
0.8041,
3.09,
1.813,
2.106,
2.38,
1.773,
0.8128,
2.047,
1.658,
0.3588
],
"window": 0,
"chr": "chr1"
},
{
"total": 35.67,
"signal": [
0.6111,
1.995,
0.5715,
2.51,
3.318,
1.523,
3.94,
2.743,
4.445,
0.759,
4.938,
2.61,
3.379,
1.27,
1.057
],
"window": 1,
"chr": "chr1"
},
{
"total": 39.14,
"signal": [
0.0589,
0.1608,
2.426,
4.673,
3.511,
3.912,
2.809,
4.197,
4.648,
2.069,
2.84,
3.878,
0.2681,
3.622,
0.06911
],
"window": 2,
"chr": "chr1"
},
{
"total": 37.45,
"signal": [
2.688,
1.235,
2.358,
1.994,
1.541,
1.189,
0.8078,
4.872,
2.287,
4.266,
2.24,
3.349,
3.519,
1.896,
3.21
],
"window": 3,
"chr": "chr1"
},
{
"total": 47.17,
"signal": [
3.338,
3.613,
3.872,
1.166,
1.828,
4.24,
1.476,
4.025,
4.144,
4.922,
2.183,
2.701,
3.825,
4.346,
1.494
],
"window": 4,
"chr": "chr1"
},
{
"total": 41.7,
"signal": [
0.2787,
1.74,
0.7557,
4.236,
2.865,
4.542,
4.113,
1.265,
4.826,
3.731,
4.931,
2.392,
2.014,
0.6566,
3.352
],
"window": 5,
"chr": "chr1"
},
{
"total": 31.43,
"signal": [
3.025,
4.399,
1.001,
4.859,
0.9173,
2.851,
2.916,
1.821,
1.228,
1.646,
0.1008,
2.09,
2.502,
0.1476,
1.924
],
"window": 6,
"chr": "chr1"
},
{
"total": 38.23,
"signal": [
1.123,
1.972,
0.5079,
4.808,
0.5669,
4.647,
2.598,
1.874,
0.8699,
4.876,
3.981,
1.503,
4.683,
2.853,
1.366
],
"window": 7,
"chr": "chr1"
},
{
"total": 44.2,
"signal": [
3.895,
0.7457,
2.208,
1.837,
3.219,
3.98,
3.494,
4.225,
3.117,
3.162,
3.171,
2.449,
0.1419,
3.745,
4.807
],
"window": 8,
"chr": "chr1"
},
{
"total": 36.33,
"signal": [
0.3164,
2.753,
4.094,
2.237,
4.748,
2.483,
1.541,
4.113,
0.1874,
3.71,
1.313,
0.221,
2.736,
1.208,
4.671
],
"window": 9,
"chr": "chr1"
},
{
"total": 43.05,
"signal": [
1.924,
0.4136,
3.057,
4.686,
1.263,
0.1333,
0.8786,
4.715,
4.845,
4.282,
2.112,
4.597,
3.822,
1.322,
4.999
],
"window": 10,
"chr": "chr1"
},
{
"total": 31.28,
"signal": [
4.216,
0.6655,
2.078,
1.235,
0.5526,
1.556,
1.005,
3.196,
1.907,
4.932,
0.006601,
1.269,
3.964,
4.608,
0.09109
],
"window": 11,
"chr": "chr1"
},
{
"total": 48.3,
"signal": [
4.469,
1.138,
3.958,
2.801,
3.404,
4.988,
2.649,
3.818,
3.284,
0.9281,
3.982,
0.496,
4.28,
3.258,
4.845
],
"window": 12,
"chr": "chr1"
},
{
"total": 42.1,
"signal": [
1.087,
3.127,
0.493,
3.276,
4.195,
1.561,
2.638,
4.897,
3.675,
4.937,
0.05847,
4.272,
2.33,
1.776,
3.776
],
"window": 13,
"chr": "chr1"
},
{
"total": 40.1,
"signal": [
1.275,
4.574,
2.805,
1.646,
0.8759,
4.948,
3.637,
3.227,
2.259,
2.983,
2.905,
4.134,
3.133,
0.08384,
1.617
],
"window": 14,
"chr": "chr1"
},
{
"total": 50.31,
"signal": [
2.228,
0.7037,
4.977,
1.143,
2.506,
4.348,
4.344,
3.998,
4.213,
2.745,
4.374,
3.411,
4.504,
4.417,
2.396
],
"window": 15,
"chr": "chr1"
},
{
"total": 34.7,
"signal": [
2.729,
3.891,
3.873,
2.973,
0.1487,
1.573,
1.781,
2.788,
2.191,
2.912,
1.355,
2.582,
2.374,
3.164,
0.3641
],
"window": 16,
"chr": "chr1"
},
{
"total": 32.89,
"signal": [
3.619,
2.119,
1.854,
4.083,
0.9916,
0.5065,
0.8343,
4.835,
1.723,
3.926,
2.675,
2.281,
0.1531,
2.239,
1.049
],
"window": 17,
"chr": "chr1"
},
{
"total": 38.94,
"signal": [
1.976,
1.587,
3.808,
0.1173,
3.823,
4.349,
3.652,
1.308,
3.434,
3.855,
1.622,
0.2916,
2.382,
3.091,
3.647
],
"window": 18,
"chr": "chr1"
},
{
"total": 34.18,
"signal": [
0.339,
3.695,
3.108,
3.267,
0.08282,
3.53,
2.316,
1.11,
4.504,
4.111,
0.007636,
0.5581,
2.985,
1.707,
2.857
],
"window": 19,
"chr": "chr1"
},
{
"total": 29.62,
"signal": [
2.695,
0.8477,
4.417,
3.012,
2.454,
2.686,
0.6529,
0.2275,
1.052,
0.2092,
2.968,
3.268,
0.7144,
0.4441,
3.973
],
"window": 20,
"chr": "chr1"
}
];
がうまくいけば、この問題を説明するために必要なすべての作業を示しています。アドバイスや指導に感謝します。
axample動作するコードを提供してください – KEKUATAN