Цвет легенды D3js не соответствует цвету карты javascript

#javascript #jquery #d3.js #leaflet #folium

Вопрос:

У меня уже есть нарисованная карта. Я хотел бы добавить легенду, используя d3.js. Например, при заполнении по длине карта должна отображать разные цвета. Уже неделю я не мог выполнить эту задачу. Мой цвет карты кажется хорошим, но легенда не совпадает. Кто-нибудь может помочь мне с моей функцией draw link ? https://jsfiddle.net/aba2s/xbn9euh0/12/)

Я думаю, что ошибка связана с функцией легенды. Вот функция, которая изменяет цвет моей карты Roads.eachLayer(function (layer) {layer.setStyle({fillColor: colorscale(layer.feature.properties.length)})});

 function drawLinkLegend(dataset, colorscale, min, max) {
    // Show label
    linkLabel.style.display = 'block'

    var legendWidth = 100
        legendMargin = 10
        legendLength = document.getElementById('legend-links-container').offsetHeight - 2*legendMargin
        legendIntervals = Object.keys(colorscale).length
        legendScale = legendLength/legendIntervals

    // Add legend

    var legendSvg = d3.select('#legend-links-svg')
                .append('g')
                .attr("id", "linkLegendSvg");

    var bars = legendSvg.selectAll(".bars")
      //.data(d3.range(legendIntervals), function(d) { return d})
      .data(dataset)
      .enter().append("rect")
        .attr("class", "bars")
        .attr("x", 0)
        .attr("y", function(d, i) { return legendMargin   legendScale * (legendIntervals - i-1); })
        .attr("height", legendScale)
        .attr("width", legendWidth-50)
        .style("fill", function(d) { return colorscale(d) })

    // create a scale and axis for the legend
    var legendAxis = d3.scaleLinear()
        .domain([min, max])
        .range([legendLength, 0]);

    legendSvg.append("g")
         .attr("class", "legend axis")
         .attr("transform", "translate("   (legendWidth - 50)   ", "   legendMargin   ")")
         .call(d3.axisRight().scale(legendAxis).ticks(10))
}
 

Комментарии:

1. Пожалуйста, помогите мне, Как вы думаете, это из-за моего data(d3.range(legendIntervals), function(d) { return d})

Ответ №1:

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

Мы хотим получить доступ к минимальным и максимальным значениям, которые будут предоставлены шкале. Для этого мы можем использовать scale.domain() which, который возвращает массив, содержащий экстент домена, минимальные и максимальные значения.

Затем мы можем создать набор данных, содержащий значения между (и включая) этими двумя конечными точками.

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

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

Что-то вроде следующей работы shold:

 var dif = colorscale.domain()[1] - colorscale.domain()[0];
var intervals = d3.range(20).map(function(d,i) {
    return dif * i / 20   colorscale.domain()[0]
}) 
intervals.push(colorscale.domain()[1]);
var intervalHeight = legendLength / intervals.length;
 
var bars = legendSvg.selectAll(".bars")
  .data(intervals)
  .enter().append("rect")
    .attr("class", "bars")
    .attr("x", 0)
    .attr("y", function(d, i) { return Math.round((intervals.length - 1 - i)  * intervalHeight)   legendMargin; })
    .attr("height", intervalHeight)
    .attr("width", legendWidth-50)
    .style("fill", function(d, i) { return colorscale(d) })
 

При устранении неполадок в существующем коде вы можете увидеть, что в DOM слишком много элементов при представлении масштаба. Кроме того, Object.keys(colorscale).length не будет генерироваться информация, полезная для генерации интервалов — ключи шкалы не зависят от данных.

напр.

Комментарии:

1. Большое спасибо, это то, что я искал. Что вы подразумеваете под «D3 ожидает, что ваш массив данных будет представлять создаваемые вами элементы. Похоже, вы передаете массив всех своих функций: но вы хотите, чтобы ваш масштаб представлял интервалы» Не могли бы вы плюс показать его в строке сценария для моего любопытства? Извините, я новичок в d3js и javascript.

2. Ключевым фактором при создании D3 была привязка данных — привязка данных из массива данных к элементам в DOM. Как правило, один элемент в массиве данных сопоставляется с одним элементом (или набором элементов) в DOM. Визуальное представление масштаба имеет интервалы, которые не зависят от объектов дороги: масштаб имеет одинаковое количество интервалов независимо от того, равно ли количество объектов 2 или миллиону, поэтому для сохранения соотношения 1:1 между данными и элементом нам необходимо создать новый набор данных (исходный набор данных объектов может не содержать одного объекта на интервал, он может иметь больше или меньше).

3. Знаете ли вы, как я могу удалить белую линию между цветом легенды?