максимальное количество элементов svg для браузера на карте

Я создаю карту с листовкой и d3. На карте будет нанесено много кругов. С точки зрения совместимости браузера существует ожидаемый предел количества элементов svg, которые может отображать браузер. Однако с точки зрения пользовательского опыта я бы предпочел, чтобы пользователь мог видеть как можно больше элементов на карте (в противном случае пользователю может потребоваться постоянно увеличивать и уменьшать масштаб и ждать, пока ajax вернет данные). Будет некоторая оптимизация, которую мне нужно рассмотреть (пользователь время ожидания пользователь против загрузки запроса сервера против того, что браузер может обрабатывать).

см. график, прямо сейчас существует ограничение на количество точек, которые возвращает сервер, и, таким образом, заполняется только часть карты.

enter image description here

браузер не может обрабатывать полностью заполненную карту здесь, и пользователю также придется слишком долго ждать ответа сервера.

Я полагаю, что проблема, с которой я столкнулся, должна быть решена путем ответа на два вопросы:

  • есть ли стандарт с точки зрения того, что средний браузер может обрабатывать с точки зрения количества простых форм svg (кругов) на карте?
  • каков наилучший способ показать как можно больше фигур на карте?

Я рассматриваю следующие моменты, но я не уверен, если это поможет;

  • используйте квадраты вместо кругов
  • используйте API листовки вместо D3

4 ответов


говоря в общих чертах, ни один из пунктов, которые вы рассматриваете поможет. В обоих случаях объем обработки / информации для отображения браузером будет примерно одинаковым.

Что касается вашего первого вопроса, то я не знаю. Существуют огромные различия между браузерами и платформами (особенно если вы рассматриваете мобильные устройства), и среднее значение было бы почти бессмысленным. Более того, это постоянно меняется. Я понял это. около 1000 простых форм обычно не проблема.

чтобы показать как можно больше фигур на карте, я бы предварительно визуализировал их в растровые плитки, а затем использовал бы API листовки или что-то вроде d3.Гео.плитка (пример здесь), чтобы наложить его на реальную карту. Таким образом, вы можете легко масштабировать до миллионов точек.


хотя вы можете отображать только ~ 2-5k SVG-элементов, прежде чем вы начнете видеть заметное замедление (в зависимости от размера, использования градиентных заливок и т. д.), вы можете хранить и управлять гораздо большими наборами данных на стороне клиента. Вы часто можете эффективно обрабатывать десятки или сотни тысяч точек данных в SVG: фокус в том, чтобы быть очень избирательным в отношении того, что вы на самом деле визуализируете, и использовать такие методы, как debouncing перерисовывать только при необходимости.

(для очень больших наборов данных: да, вам потребуется либо совокупного/подвыборке очки или рендеренные.)

имея это в виду, один из методов, который я использовал для карт d3, в частности, использовать d3.geom.quadtree() динамически отбирать очки при сдвиге/зумирования. Более конкретно, я избегаю рисования точек, которые являются либо

  1. вне текущего ограничивающего поля карты (поскольку они вообще не видны) или
  2. слишком близко к другим точкам (так как они добавляют визуальный беспорядок и трудно взаимодействовать с в любом случае).

в псевдокоде JS-ish это будет выглядеть примерно так:

function getIndicesToDraw(data, r, bbox) {
  var indicesToDraw = [];
  var Q = d3.geom.quadtree();
  // set bounds in pixel space
  for (var i = 0; i < data.length; i++) {
    var d = data[i];
    var p = getPointForDatum(d);
    if (isInsideBoundingBox(bbox, p) && !hasPointWithinRadius(Q, r, p)) {
      Q.add(p); 
      indicesToDraw.push(i);
    }
  }
  return indicesToDraw;
}

function redraw(svg, data, r, bbox) {
  var indicesToDraw = getIndicesToDraw(data, r, bbox);
  var points = svg.selectAll('.data-point')
    .data(indicesToDraw, function(i) { return i; });

  // draw new points for points.enter()

  points.exit().remove();

  // update positions of points (or SVG transforms, etc.)
}

Я бы загрузил все данные сразу, но только рисовал круги в порту просмотра, которые достаточно велики. При масштабировании или панорамировании удалите круги, которые не должны отображаться, и проверьте, следует ли добавлять ранее скрытые круги.


Это вопрос картографии так же, как и технологии. Только потому, что ты!--1-- > can поставить тысяч точек на карте не означает, что вы должны. Вы должны спросить себя, Должен ли ваш пользователь видеть как можно больше точек одновременно и будет лучше понимать данные в результате этого. Будет ли видеть это много точек смущать и подавлять пользователя, или это поможет им выполнить желаемую задачу? Есть ли способ фильтровать данные так, чтобы все очки не нужно рисовать сразу?

наиболее распространенным решением этой проблемы является использование кластеров, как правило, с чем-то вроде Листовка MarkerCluster. В прошлом, используя D3 и листовку, я создал своего рода тепловую карту, создав произвольную сетку, назначив каждую точку в ячейку и применив цветовую рампу к сетке. Однако, возвращаясь к вашей первоначальной проблеме, она довольно вычислительно интенсивна.

в зависимости от того, какие платформы вы хотите поддержать, имейте в виду, что телефоны и планшеты не всегда справляются с SVGs очень хорошо, особенно при рисовании тысяч функций.

другое место для потенциального увеличения производительности - это доставка геометрии точки. Я не уверен, как вы загружаете их в настоящее время, но использование пространственно индексированной таблицы PostGIS и выбор по ограничению часто довольно быстро, но поскольку вы рисуете точки, а не полигоны, вы можете даже уйти от загрузки их в браузер через CSV, который существенно меньше, чем GeoJSON или Topojson.