По сути, я пытаюсь перейти с svg на основанный на холсте график, чтобы улучшить fps для больших наборов данных.
Я использовал d3 (v3) принудительное расположение для представления сети узлов и ссылок, и язаметил снижение производительности по мере увеличения количества элементов svg на экране.Чтобы предотвратить это, я начал рассматривать холст как возможную альтернативу и увидел некоторые интересные результаты в Интернете.Я полностью преобразовал свой код, чтобы рисовать те же самые вещи на холсте вместо svg, сохраняя при этом характеристики раскладки d3.
this._mainCanvas = d3.select(this._container).append('canvas')
.attr('width', this._width)
.attr('height', this._height);
this._mainContext = this._mainCanvas.node().getContext('2d');
this._simulation = d3.layout
.force()
.size([this._width, this._height])
.gravity(0.35)
.charge(-2000)
.theta(0.85)
.alpha(0.05)
.friction(0.7)
.nodes(this.data.nodes)
.links(this.data.relationships)
.linkDistance(1000)
.linkStrength(this._linkStrength)
.on('tick', self._tick())
.start();
this._tick() {
this._mainContext.clearRect(0, 0, this._width, this._height);
// draw links
this.data.relationships.forEach(function (d) {
self._mainContext.strokeStyle = 'rgba(128, 128, 128, 0.5)';
self._mainContext.beginPath();
self._mainContext.moveTo(d.source.x, d.source.y);
self._mainContext.lineTo(d.target.x, d.target.y);
self._mainContext.lineWidth = d.linkWeight;
self._mainContext.stroke();
});
this.data.nodes.forEach(function (d) {
// Node
self._mainContext.fillStyle = d.color;
self._mainContext.beginPath();
self._mainContext.moveTo(d.x, d.y);
self._mainContext.arc(d.x, d.y, d.radius, 0, 2 * Math.PI);
self._mainContext.strokeStyle = d3.rgb(d.color).darker(1);
self._mainContext.lineWidth = 2;
self._mainContext.stroke();
self._mainContext.fill();
self._mainContext.closePath();
// Text
self._mainContext.font = parseInt(Math.round(d.radius * 0.75)) + 'px' + ' Open Sans';
self._mainContext.textBaseline = 'middle';
self._mainContext.textAlign = 'start';
self._mainContext.fillStyle = 'black';
self._mainContext.fillText(d.value, d.x + parseInt(Math.round(d.radius * 1.25)), d.y);
// Icon
self._mainContext.font = parseInt(Math.round(d.radius * 0.75)) + 'px' + ' FontAwesome';
self._mainContext.textBaseline = 'middle';
self._mainContext.textAlign = 'center';
self._mainContext.fillStyle = 'white';
self._mainContext.fillText(d.icon, d.x, d.y);
});
}
Конечный результат был весьма разочаровывающим, производительность не улучшилась ни на один бит вместо того, чтоЯ ожидал чтения в Интернете и тестирования различных примеров.Так что мне интересно, что я делаю не так?Любая помощь будет высоко оценена, спасибо заранее.
Вот некоторые примеры, на которые я ссылаюсь: