#javascript #json #d3.js #data-visualization
#javascript #json #d3.js #визуализация данных
Вопрос:
Обучаясь самостоятельно и будучи новичком в D3.js , Я пытаюсь создать несколько круговых диаграмм с разными категориями, переключаемыми пользовательскими кнопками.
Я создал отдельную круговую диаграмму с эффектом: https://bl.ocks.org/lydiawawa/7c385eaaf24cb4e6047c9b56866fac6e/252dfbf9f27123e5577f6c54ca7dffe6fd75714e
Я надеюсь добиться следующего эффекта с помощью всплывающей подсказки и метки, но вместо orange и apple я хотел бы переключаться между полом, возрастом и расой:
Желаемый эффект: http://bl.ocks.org/j0hnsmith/5591116
Это то, что у меня есть до сих пор: https://blockbuilder.org/lydiawawa/38243015ab2ac96b6086d3bae56572b9
Самая сложная часть — преобразование круговой диаграммы с двумя категориями в три категории с добавлением всплывающей подсказки и метки. Я хотел бы получить некоторую помощь в достижении эффекта. Спасибо за любой вклад!
Редактировать
Недавно я обнаружил следующий эффект с тремя категориями, но я не знаю, как добавить метку или легенду к графику, которые позже можно использовать и для всплывающей подсказки:
http://bl.ocks.org/jfreels/6919598
Я попытался изменить формат json в следующем формате. Может быть, таким образом мы можем использовать d3.json вместо init()?
[
{
"genderC": "female",
"gender": 533,
"raceC": "A",
"race": 20,
"ageC": "0 < 12 years",
"age": 8
},
{
"genderC": "male",
"gender": 260,
"raceC": "A E",
"race": 19,
"ageC": "13 years",
"age": 1
},
{
"genderC": "",
"gender": null,
"raceC": "A D",
"race": 2,
"ageC": "14 years",
"age": 102
},
{
"genderC": "",
"gender": null,
"raceC": "A DE",
"race": 1,
"ageC": "15 years",
"age": 195
},
{
"genderC": "",
"gender": null,
"raceC": "A C",
"race": 5,
"ageC": "16 years",
"age": 200
},
{
"genderC": "",
"gender": null,
"raceC": "A C E",
"race": 5,
"ageC": "17 years",
"age": 187
},
{
"genderC": "",
"gender": null,
"raceC": "AB D",
"race": 1,
"ageC": "18 years",
"age": 100
},
{
"genderC": "",
"gender": null,
"raceC": "ABC E",
"race": 1,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "ABCD",
"race": 1,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "ABCDE",
"race": 1,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "B",
"race": 27,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "B H",
"race": 0,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "B E",
"race": 6,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "B D",
"race": 6,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "B DE",
"race": 2,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "BC",
"race": 2,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "BCD",
"race": 1,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "C",
"race": 175,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "C E",
"race": 17,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "CD",
"race": 3,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "D",
"race": 14,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "DE",
"race": 3,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "E",
"race": 481,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
},
{
"genderC": "",
"gender": null,
"raceC": "",
"race": null,
"ageC": "",
"age": null
}
]
Комментарии:
1. Я просматриваю blockbuilder, которым вы поделились, и я немного сбит с толку, каковы ваши окончательные данные? В blockbuilder у вас есть ваши данные в dataset.json, но это просто javascript, поскольку у вас есть массивы объектов
var gender = [{..}],{..}]
. Если ваши данные уже представлены в виде массивов объектов, вам не нужно создавать json. Иметь их в качестве отдельных переменных на самом деле проще.2. @Coola Я импортировал json в виде скрипта в index.html и массивы были вызваны в init() . Вы имеете в виду, что мне не нужно вызывать его index.html ? Я могу просто определить массивы в PieChart()?
3. @Coola Я думаю, что я надеюсь просто использовать свой собственный набор данных для создания трех круговых диаграмм, переключаемых кнопками. Переход будет иметь эффект от этого примера: bl.ocks.org/j0hnsmith/5591116 с надписью или меткой, обозначающей цвета. Эффект всплывающей подсказки также будет добавлен для отображения процента.
4. Да, вы можете просто определить массивы внутри
main.js
. Я понимаю, чего бы вы хотели, но копирование кода из других источников без понимания того, что они делают, приводит к тому, что ваш текущий блок немного запутывается.5. @Coola Я переместил эти переменные в init() в main.js . Код обновляется.
Ответ №1:
В вашем коде было несколько проблем, и мне пришлось внести несколько изменений.
Если я правильно понимаю, основная идея для вас заключалась в том, чтобы перерисовать круговые диаграммы в зависимости от того, на какие данные нажимает пользователь, например, «Пол», «Возраст» или «Раса».
- Данные для каждого из них очень разные, то есть разные пары ключ-значение объекта. Я сделал все
count
ключи одинаковыми (в наборе данных age они былиCount
). - Поскольку данные сильно отличаются друг от друга, примеры, которые вы показываете, когда данные обновляются, могут здесь не применяться, поскольку в этом случае данные не преобразуются. Вместо этого подход, который я использовал, состоял в том, чтобы просто очистить div и перерисовать круговую диаграмму. Итак, первое, что он делает, это очищает область диаграммы, а затем начинает рисовать. Это значительно сокращает объем необходимого кода (ваш main.js = > 300 строк, тогда как у меня 138 строк)
- Я улучшил всплывающую подсказку по мере изменения ваших ключей данных, поэтому это необходимо учитывать во всплывающей подсказке.
- Я переместил ваши данные в отдельный js-файл, чтобы не загромождать main.js . Я просто обязательно вызываю это перед main.js в index.html досье.
- Я обновил
function color(d)
функцию, чтобы выбирать цвета из массива объектов на основе ключей данных. Вы можете расширить массив в соответствии с вашими потребностями. Если вы хотите использовать цвета в пределах диапазона, вы можете использоватьvar color = d3.scale.category20();
и вызывать цвет, используя индекс данных.attr("fill", function (d, i) { return color(i);})
, как показано в этом примере http://bl.ocks.org/j0hnsmith/5591116
Вот рабочий блок https://bl.ocks.org/akulmehta/923f277f8a10d0c35b77f6e3a84929bf /
Обратите внимание, что, поскольку много точек данных для age
и race
есть 0
, анимация немного заикается. Также обратите внимание, что ваши метки перекрываются, когда дуги расположены очень близко друг к другу. Поэтому я бы предложил удалить метки.
Комментарии:
1. Спасибо вам за все. Вы даже выбрали цвета для категориальной переменной. Я рассмотрю / изучу код и внесу некоторые изменения, как только вернусь домой сегодня.
2. Я приму ответ, как только вернусь домой, мое приложение по какой-то причине не позволяет мне отмечать проверку.
3. Я попытался внести несколько изменений в ваш отредактированный код. Я добавил условия в оператор else для цветов, которые определяли бы категории расы, но график гонки не появился после изменения. Я также пытался добавить легенду к графику после удаления меток, но легенда тоже не появляется. Это старая ссылка с моими обновлениями: blockbuilder.org/lydiawawa/38243015ab2ac96b6086d3bae56572b9
4. Я приму ответ сейчас, но не могли бы вы помочь сделать последние несколько дополнений. Я думаю, что я довольно близок, но по какой-то причине эффекты не отображаются.
5. Как насчет этого blockbuilder.org/akulmehta/1aa16d77c876b213d982c54a8e86e434 ? При вызове функции color в функцию передается дополнительная информация, чтобы сообщить ей, какой это тип данных и длина данных. Делая это, вы можете использовать его для использования порядковых шкал для получения значения цвета. Надеюсь, это поможет.