страница "Статистика"
This commit is contained in:
@@ -123,6 +123,8 @@ if DEBUG: # DEBUG: заменяем настройки прода, на на
|
|||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
MY_STATIC_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_ROOT_DEV2,
|
MY_STATIC_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_ROOT_DEV2,
|
||||||
]
|
]
|
||||||
|
# путь к каталогу static (в эту переменную использовать для указания пути где будут делаться кэш-блоки для шаблонов)
|
||||||
|
STATIC_BASE_PATH = MY_STATIC_BASE_PATH_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_BASE_PATH_DEV2
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': "django.db.backends.mysql",
|
'ENGINE': "django.db.backends.mysql",
|
||||||
@@ -137,8 +139,10 @@ if DEBUG: # DEBUG: заменяем настройки прода, на на
|
|||||||
TOUCH_RELOAD = MY_TOUCH_RELOAD_PROD
|
TOUCH_RELOAD = MY_TOUCH_RELOAD_PROD
|
||||||
else:
|
else:
|
||||||
MEDIA_ROOT = MY_MEDIA_ROOT_PROD
|
MEDIA_ROOT = MY_MEDIA_ROOT_PROD
|
||||||
STATIC_ROOT = MY_STATIC_ROOT_PROD
|
|
||||||
# STATICFILES_DIRS = [MY_STATIC_ROOT_PROD1, ]
|
# STATICFILES_DIRS = [MY_STATIC_ROOT_PROD1, ]
|
||||||
|
STATIC_ROOT = MY_STATIC_ROOT_PROD
|
||||||
|
# путь к каталогу static (в эту переменную использовать для указания пути где будут делаться кэш-блоки для шаблонов)
|
||||||
|
STATIC_BASE_PATH = MY_STATIC_BASE_PATH_PROD
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': "django.db.backends.mysql",
|
'ENGINE': "django.db.backends.mysql",
|
||||||
|
|||||||
0
oknardia/oknardia/templatetags/__init__.py
Executable file
0
oknardia/oknardia/templatetags/__init__.py
Executable file
@@ -18,7 +18,7 @@ from django.contrib import admin
|
|||||||
from django.urls import path, re_path
|
from django.urls import path, re_path
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from oknardia.settings import *
|
from oknardia.settings import *
|
||||||
from web import views, autocomplete_addr, user_manager, blog
|
from web import views, autocomplete_addr, user_manager, blog, diagrams
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
@@ -47,6 +47,7 @@ urlpatterns = [
|
|||||||
# САТИЧЕСКИЕ СТРАНИЦЫ
|
# САТИЧЕСКИЕ СТРАНИЦЫ
|
||||||
re_path(r'^tariff$', views.tariff),
|
re_path(r'^tariff$', views.tariff),
|
||||||
re_path(r'^contact', views.contact),
|
re_path(r'^contact', views.contact),
|
||||||
|
re_path(r'^stat_all$', diagrams.statistic_menu),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
189
oknardia/templates/seria_info/all_stat.html
Executable file
189
oknardia/templates/seria_info/all_stat.html
Executable file
@@ -0,0 +1,189 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% load filters %}
|
||||||
|
{% load humanize %}
|
||||||
|
|
||||||
|
{% block Title %} Статистика типового строительства СССР и России.{% endblock %}
|
||||||
|
|
||||||
|
{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %}
|
||||||
|
|
||||||
|
{# block Date4Meta %}{{ META_DATA_PUBLISH|date:"c" }}{% endblock #}
|
||||||
|
|
||||||
|
{# block Last4Meta %}{{ META_DATA_PUBLISH|date:"c" }}{% endblock #}
|
||||||
|
|
||||||
|
{% block Description %}Статистика типового строительства СССР и России. Географи, график ввода в эксплуатацтяю, метраж. Здания проектов серии: {% for CountSeria in SERIA_NAV_DIM %}{{ CountSeria.SERIA_R }}{% if not forloop.last %}, {% endif %}{% endfor %}.{% endblock %}
|
||||||
|
|
||||||
|
{% block Keywords %}типовые проекты зданий, панельное строительство, {% for CountSeria in SERIA_NAV_DIM %}серия {{ CountSeria.SERIA_R }}, {{ CountSeria.SERIA_R }}, {% endfor %}, года простойки, регионы построки, распространенность{% endblock %}
|
||||||
|
|
||||||
|
{% block Top_JS1%}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(window).load(function(){let images = $('.half');images.each(function(i){$(this).width($(this).width()/2);});});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block Main_Content %}<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-9"><h1>Статистика</h1></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10"><a name="s_graph"></a>
|
||||||
|
<h2 class="header">Распределение типовых серии в жилом фонде<sup><small style="color: darkred;">*</small></sup></h2>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
step = Math.round( Math.pow({{ SERIA_NAV_DIM|length }}, 1./3.)-1);
|
||||||
|
step_tone = Math.floor(0xF0/step)-1;
|
||||||
|
DimColor = [];
|
||||||
|
for (i1=0; i1<=step; i1++ )
|
||||||
|
for (i2=step; i2>=0; i2-- )
|
||||||
|
for (i3=0; i3<=step; i3++ ) {
|
||||||
|
//document.write(" <span style='color:#"
|
||||||
|
// + ("00"+(i1*step_tone).toString(16)).substr(-2)
|
||||||
|
// + ("00"+(i2*step_tone).toString(16)).substr(-2)
|
||||||
|
// + ("00"+(i3*step_tone).toString(16)).substr(-2)
|
||||||
|
// + ";'>█</span> -- ");
|
||||||
|
//document.write( "#"
|
||||||
|
// + ("00"+(i1*step_tone).toString(16)).substr(-2)
|
||||||
|
// + ("00"+(i2*step_tone).toString(16)).substr(-2)
|
||||||
|
// + ("00"+(i3*step_tone).toString(16)).substr(-2) + "<br>");
|
||||||
|
DimColor.push("#"
|
||||||
|
+ ("00"+(i1*step_tone).toString(16)).substr(-2)
|
||||||
|
+ ("00"+(i2*step_tone).toString(16)).substr(-2)
|
||||||
|
+ ("00"+(i3*step_tone).toString(16)).substr(-2)
|
||||||
|
);
|
||||||
|
}{% for CountSeria in SERIA_NAV_DIM %}
|
||||||
|
c{{ CountSeria.ID2URL }} = DimColor[{{ forloop.counter0 }}]; s{{ CountSeria.ID2URL }} = "{{ CountSeria.SERIA_R }}"; {% endfor %} sNone = "нет данных";
|
||||||
|
|
||||||
|
google.load("visualization", "1", {packages:["corechart"]});
|
||||||
|
google.setOnLoadCallback(drawChart);
|
||||||
|
function drawChart() {
|
||||||
|
|
||||||
|
let dataNumBuildingPerSeria = google.visualization.arrayToDataTable([
|
||||||
|
[ 'Проект серии', 'Число зданий (шт.)' ],{% for CountSeria in DATA2PIE %}
|
||||||
|
[ 'Серия ' + s{{ CountSeria.ID }}, {{ CountSeria.NUM_BUILDING }} ]{% if not forloop.last %},{% endif %}{% endfor %}
|
||||||
|
]);
|
||||||
|
let dataM2PerSeria = google.visualization.arrayToDataTable([
|
||||||
|
[ 'Проект серии', 'Общая площадь помещений в данно серии (м2)' ],{% for CountSeria in DATA2PIE %}
|
||||||
|
[ 'Серия ' + s{{ CountSeria.ID }}, {{ CountSeria.AREA_M2|stringformat:"f" }} ]{% if not forloop.last %},{% endif %}{% endfor %}
|
||||||
|
]);
|
||||||
|
let TotalKnown = {% for CountSeria in DATA2PIE %}{{ CountSeria.NUM_BUILDING }}{% if not forloop.last %}+{% endif %}{% endfor %};
|
||||||
|
let TotalAddress = 114808;
|
||||||
|
let dataTotal = google.visualization.arrayToDataTable([
|
||||||
|
[ 'База «Окнардии»', 'Количество адресов' ],
|
||||||
|
[ 'Не обработано или нет данных', TotalAddress-TotalKnown ],
|
||||||
|
[ 'Оцифрованые типовые серии', TotalKnown ]
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
let options4Pie1 = {
|
||||||
|
pieHole: 0.386,
|
||||||
|
//backgroundColor:'#f1fff1',
|
||||||
|
legend: {position: "none"},
|
||||||
|
//chartArea: {left:20,top:10,width:'100%',height:'100%'},
|
||||||
|
chartArea: {width: '95%', height: '95%'},
|
||||||
|
slices: { {% for CountSeria in DATA2PIE %}
|
||||||
|
{{ forloop.counter0 }}: { color: c{{ CountSeria.ID }} }{% if not forloop.last %},{% endif %}{% endfor %}
|
||||||
|
},
|
||||||
|
//colors: [ {% for CountSeria in DATA2PIE %} c{{ CountSeria.ID }} {% if not forloop.last %},{% endif %}{% endfor %} ],
|
||||||
|
pieStartAngle: 30,
|
||||||
|
//is3D: true,
|
||||||
|
pieSliceTextStyle: {fontSize: 12},
|
||||||
|
tooltip: {textStyle: {fontSize: 14, color: 'black', opacity: 0.8}, showColorCode: true}
|
||||||
|
};
|
||||||
|
let options4Pie2 = {
|
||||||
|
pieHole: 0.16,
|
||||||
|
legend: {position: "none"},
|
||||||
|
chartArea: {width: '90%', height: '95%', top: 8, left:8},
|
||||||
|
pieStartAngle: 115,
|
||||||
|
slices: { 1: {offset: 0.04}},
|
||||||
|
pieSliceTextStyle: {fontSize: 12},
|
||||||
|
tooltip: {textStyle: {fontSize: 10, color: 'black', opacity: 0.8}, showColorCode: true}
|
||||||
|
};
|
||||||
|
|
||||||
|
let chartNumBuildingPerSeria = new google.visualization.PieChart(document.getElementById('donutchart1'));
|
||||||
|
let chartM2PerSeria = new google.visualization.PieChart(document.getElementById('donutchart2'));
|
||||||
|
let chartTotsl = new google.visualization.PieChart(document.getElementById('donutchart3'));
|
||||||
|
chartNumBuildingPerSeria.draw(dataNumBuildingPerSeria, options4Pie1);
|
||||||
|
chartM2PerSeria.draw(dataM2PerSeria, options4Pie1);
|
||||||
|
chartTotsl.draw(dataTotal, options4Pie2);
|
||||||
|
}
|
||||||
|
$(window).load(function(){ {% for CountSeria in SERIA_NAV_DIM %}$(".cc{{ CountSeria.ID2URL }}").css("color",c{{ CountSeria.ID2URL }}); {% endfor %}});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h4 style="text-align:center;">Количество зданий типовых проектов<sup><small style="color: darkred;">*</small></sup></h4>
|
||||||
|
<div id="donutchart1" style="height:350px;width:100%;"></div>
|
||||||
|
<div style="font-size: xx-small;float: right">© 2015-{% now "Y" %}, данные: oknardia.ru</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h4 style="text-align:center;">Общая площадь (м²) в типовых сериях<sup><small style="color: darkred;">*</small></sup></h4>
|
||||||
|
<div id="donutchart2" style="height:350px;width:100%;"></div>
|
||||||
|
<div style="font-size: xx-small;float: right">© 2015-{% now "Y" %}, данные: oknardia.ru</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-md-offset-1">
|
||||||
|
<h4>Адресная база «Окнардия»<sup><small style="color: darkred;">*</small></sup></h4>
|
||||||
|
<div id="donutchart3" style="height:180px;width:100%;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h4>Обозначения:</h4>
|
||||||
|
<diV style="font-size: small;">{% for CountSeria in SERIA_NAV_DIM %}
|
||||||
|
<span style="display:inline-flex;width: 22.5%;"><nobr><span class="cc{{ CountSeria.ID2URL }}">█</span> <a href="/catalog/seria/{{ CountSeria.SERIA_L }}/all{{ CountSeria.ID2URL }}/">{{ CountSeria.SERIA_R }}</a></nobr></span>{% endfor %}
|
||||||
|
</diV>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||||||
|
<script src="{% static 'js/ymaps-pie-chart-clusterer.js' %}" type="text/javascript"></script>
|
||||||
|
<script src="{% static '' %}{{ MAP_JS }}" charset="utf-8" type="text/javascript"></script>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12"><a name="s_map"></a>
|
||||||
|
<h2 class="header">Здания типовых проектов на карте:</h2></div>
|
||||||
|
<div class="col-xs-1" style="font-size: x-small;">
|
||||||
|
<h6>Обозначения:</h6>
|
||||||
|
<p style="margin-left:1ex;">{% for CountSeria in SERIA_NAV_DIM %}
|
||||||
|
<nobr><span class="cc{{ CountSeria.ID2URL }}">█</span> <a href="/catalog/seria/{{ CountSeria.SERIA_L }}/all{{ CountSeria.ID2URL }}/">{{ CountSeria.SERIA_R }}</a></nobr><br/>{% endfor %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-11">
|
||||||
|
<div id="SeriaMap" style="height:650px;width:100%;">
|
||||||
|
<p style="font-size:small;padding-top: 1ex;">Чтобы посмотреть цены на установку и замену окон от партнёров «Окнардия» в своей квартире: найдите дом на карте; кликните на него; перейдите по ссылке «Смотреть цены на установку окон». При необходимости смените типовую планировку квартиры (на странице ценовой выдачи, справа от изображения типовых проёмов и схем открывания).</p>
|
||||||
|
<noscript><p>Для отображения картографических данных с помощью «Яндекс.Карт» нужно включить поддержку JavaScript.</p></noscript>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: xx-small;float: right">© 2015-{% now "Y" %}, данные: oknardia.ru</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- div class="row col-md-12">
|
||||||
|
<div class="col-md-8 header"><a name="s_graph"></a>
|
||||||
|
<h2>Возведение зданий разных серий по годам</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||||
|
{% now "Y" %}<br>
|
||||||
|
{#% include 'SeriaInfo/yaer_graph.html' %#}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row col-md-12">
|
||||||
|
<div class="col-md-8 header"><a name="s_graph"></a>
|
||||||
|
<h2>Метраж в эксплуатации по годам</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
|
||||||
|
{#% include 'SeriaInfo/yaer_graph.html' %#}
|
||||||
|
</div>
|
||||||
|
</div -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2 col-md-offset-10" style="margin-top: 4em;"><p style="font-size:xx-small;">время исполнения скрипта: {{ ticks|floatformat:4 }}</p></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
|
{% block Top_Nav_Bar %}
|
||||||
|
{# ОТЛАДКА, ГАСИМ ВЕРХНЕЕ МЕНЮ #}
|
||||||
|
{% endblock %}
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
110
oknardia/web/diagrams.py
Normal file
110
oknardia/web/diagrams.py
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from time import time
|
||||||
|
from oknardia.models import Seria_Info
|
||||||
|
from oknardia.settings import *
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import pytils # вместо Rus2Lat(smth) --> pytils.translit.slugify(smth).lower()
|
||||||
|
|
||||||
|
|
||||||
|
# возвращает корректный SeriaID и кортеж для построения навигации по сериям дома
|
||||||
|
def seria_nav(i_seria_id: int = 12) -> (int, dict):
|
||||||
|
query_seria = Seria_Info.objects.raw(
|
||||||
|
'SELECT oknardia_seria_info.id,'
|
||||||
|
' oknardia_seria_info.sName,'
|
||||||
|
' oknardia_seria_info.sSeriaDescription,'
|
||||||
|
' oknardia_seria_info.kRoot_id,'
|
||||||
|
' oknardia_seria_info.kParent_id '
|
||||||
|
'FROM oknardia_seria_info '
|
||||||
|
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
|
||||||
|
'ORDER BY oknardia_seria_info.sName;')
|
||||||
|
error_seria = True
|
||||||
|
for count_seria in query_seria:
|
||||||
|
if count_seria.id == int(i_seria_id):
|
||||||
|
error_seria = False
|
||||||
|
break
|
||||||
|
if error_seria:
|
||||||
|
# Ошибочный SeriaID. Такой базовой серии нет и надо ее найти.
|
||||||
|
try:
|
||||||
|
query = Seria_Info.objects.get(id=int(i_seria_id))
|
||||||
|
if query.kRoot_id is None:
|
||||||
|
# базовая серия прописана в kRoot_id
|
||||||
|
i_seria_id = query.kRoot_id
|
||||||
|
else:
|
||||||
|
# == корневой нет
|
||||||
|
# == ищем методом наименьших расстояний
|
||||||
|
min_min = 100000000
|
||||||
|
min_id = i_seria_id
|
||||||
|
for count_seria in query_seria:
|
||||||
|
if math.fabs(int(i_seria_id) - count_seria.id) < min_min:
|
||||||
|
min_min = math.fabs(int(i_seria_id) - count_seria.id)
|
||||||
|
min_id = count_seria.id
|
||||||
|
i_seria_id = min_id
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
i_seria_id = query_seria[0].id
|
||||||
|
# print("-->", SeriaID, "<--")
|
||||||
|
seria_nav_dim = []
|
||||||
|
this_return = {}
|
||||||
|
for count_seria in query_seria:
|
||||||
|
one_seria = {}
|
||||||
|
one_seria.update({"SERIA_R": count_seria.sName, "ID2URL": count_seria.id})
|
||||||
|
if count_seria.id == i_seria_id:
|
||||||
|
this_return.update({"THIS_SERIA_NAME": count_seria.sName,
|
||||||
|
"THIS_SERIA_DESCRIPTION": count_seria.sSeriaDescription})
|
||||||
|
one_seria.update({"SERIA_L": ""})
|
||||||
|
else:
|
||||||
|
one_seria.update({"SERIA_L": pytils.translit.slugify(count_seria.sName)})
|
||||||
|
seria_nav_dim.append(one_seria)
|
||||||
|
this_return.update({"SERIA_NAV_DIM": seria_nav_dim})
|
||||||
|
return i_seria_id, this_return
|
||||||
|
|
||||||
|
|
||||||
|
def statistic_menu(request: HttpRequest) -> HttpResponse:
|
||||||
|
""" Страница "Статистика" в главном меню
|
||||||
|
|
||||||
|
ВНИМАНИЕ: ТЕХНИЧЕСКИЙ ДОЛГ -- выводятся данные только по сериям зданий. Этого маловато.
|
||||||
|
Можно добавить данные по проемам, предложениям, график распределения цен и т.п.
|
||||||
|
|
||||||
|
:param request: HttpRequest -- входящий http-запрос
|
||||||
|
:return: HttpResponse -- исходящий http-ответ
|
||||||
|
"""
|
||||||
|
time_start = time()
|
||||||
|
template = "seria_info/all_stat.html"
|
||||||
|
to_template = {}
|
||||||
|
seria_id, for_seria_nav = seria_nav(0)
|
||||||
|
to_template.update(for_seria_nav)
|
||||||
|
# проверяем какой JS с картами и PieCharts: упакованные или нет.
|
||||||
|
path_name = f"{STATIC_BASE_PATH}/{PATH_FOR_JS_MAP}"
|
||||||
|
print(path_name)
|
||||||
|
if os.path.isfile(f"{path_name}/_ALL{SUFFIX_FOR_MINI_JS_MAP}"):
|
||||||
|
to_template.update({'MAP_JS': f"{PATH_FOR_JS_MAP}/_ALL{SUFFIX_FOR_MINI_JS_MAP}"})
|
||||||
|
else:
|
||||||
|
to_template.update({'MAP_JS': f"{PATH_FOR_JS_MAP}/_ALL{SUFFIX_FOR_JS_MAP}"})
|
||||||
|
|
||||||
|
# строим диаграмму сколько каких серий и каковы их площади...
|
||||||
|
q_seria_pie = Seria_Info.objects.raw(
|
||||||
|
"SELECT"
|
||||||
|
" oknardia_seria_info.kRoot_id as id,"
|
||||||
|
" COUNT(oknardia_building_info.id) AS num_building,"
|
||||||
|
" SUM(oknardia_building_info.fTotal_Area) AS areaM2 "
|
||||||
|
"FROM oknardia_building_info"
|
||||||
|
" INNER JOIN oknardia_seria_info"
|
||||||
|
" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
|
||||||
|
"WHERE oknardia_seria_info.kRoot_id IS NOT NULL "
|
||||||
|
"GROUP BY oknardia_seria_info.kRoot_id "
|
||||||
|
"ORDER BY num_building DESC;")
|
||||||
|
data2pie = []
|
||||||
|
for count in q_seria_pie:
|
||||||
|
data2pie.append({
|
||||||
|
"ID": count.id,
|
||||||
|
"AREA_M2": count.areaM2,
|
||||||
|
"NUM_BUILDING": count.num_building
|
||||||
|
})
|
||||||
|
# print data2pie
|
||||||
|
to_template.update({'DATA2PIE': data2pie})
|
||||||
|
|
||||||
|
to_template.update({'ticks': float(time()-time_start)})
|
||||||
|
return render(request, template, to_template)
|
||||||
1
public/static/js/4maps/_ALL_seria_on_map.mini.js
Executable file
1
public/static/js/4maps/_ALL_seria_on_map.mini.js
Executable file
File diff suppressed because one or more lines are too long
372
public/static/js/ymaps-pie-chart-clusterer.js
Executable file
372
public/static/js/ymaps-pie-chart-clusterer.js
Executable file
@@ -0,0 +1,372 @@
|
|||||||
|
!function (t) {
|
||||||
|
var e = {modules: t.ymaps.modules};
|
||||||
|
!function (t) {
|
||||||
|
if ("undefined" == typeof t && "function" == typeof require)var t = require("ym");
|
||||||
|
t.define("util.providePackage", ["system.mergeImports"], function (t, e) {
|
||||||
|
t(function (t, n) {
|
||||||
|
var o = n[0], r = Array.prototype.slice.call(n, 1), a = e.joinImports(t.name, {}, t.deps, r);
|
||||||
|
o(a)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}(e.modules);
|
||||||
|
|
||||||
|
|
||||||
|
e.modules.define('PieChartClusterer', [
|
||||||
|
'Clusterer',
|
||||||
|
'util.defineClass',
|
||||||
|
'util.extend',
|
||||||
|
'PieChartClusterer.icon.params',
|
||||||
|
'PieChartClusterer.component.Canvas'
|
||||||
|
], function (provide,
|
||||||
|
Clusterer,
|
||||||
|
defineClass,
|
||||||
|
extend,
|
||||||
|
iconParams,
|
||||||
|
PieChartClustererCanvas) {
|
||||||
|
|
||||||
|
var STYLE_REG_EXP = /#(.+?)(?=Icon|DotIcon|StretchyIcon|CircleIcon|CircleDotIcon)/;
|
||||||
|
|
||||||
|
var PieChartClusterer = defineClass(function (options) {
|
||||||
|
PieChartClusterer.superclass.constructor.call(this, options);
|
||||||
|
|
||||||
|
this._canvas = new PieChartClustererCanvas(iconParams.icons.large.size);
|
||||||
|
this._canvas.options.setParent(this.options);
|
||||||
|
}, Clusterer, {
|
||||||
|
createCluster: function (center, geoObjects) {
|
||||||
|
// Создаем метку-кластер с помощью стандартной реализации метода.
|
||||||
|
var clusterPlacemark = PieChartClusterer.superclass.createCluster.call(this, center, geoObjects);
|
||||||
|
var styleGroups = geoObjects.reduce(function (groups, geoObject) {
|
||||||
|
// получаем в style цвет указаный в iconColor
|
||||||
|
var style = geoObject.options.get('iconColor', null);
|
||||||
|
// eсли iconColor не указан - берем значение из preset'а
|
||||||
|
if (style === null) {
|
||||||
|
var style = getIconStyle(geoObject.options.get('preset', 'islands#blueIcon'));
|
||||||
|
};
|
||||||
|
//document.write( style + "<br>" );
|
||||||
|
|
||||||
|
groups[style] = ++groups[style] || 1;
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}, {});
|
||||||
|
var iconUrl = this._canvas.generateIconDataURL(styleGroups, geoObjects.length);
|
||||||
|
var clusterOptions = {
|
||||||
|
clusterIcons: [
|
||||||
|
extend({href: iconUrl}, iconParams.icons.small),
|
||||||
|
extend({href: iconUrl}, iconParams.icons.medium),
|
||||||
|
extend({href: iconUrl}, iconParams.icons.large)
|
||||||
|
],
|
||||||
|
clusterNumbers: iconParams.numbers
|
||||||
|
};
|
||||||
|
|
||||||
|
clusterPlacemark.options.set(clusterOptions);
|
||||||
|
|
||||||
|
return clusterPlacemark;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getIconStyle(preset) {
|
||||||
|
return preset.match(STYLE_REG_EXP)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
provide(PieChartClusterer);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
e.modules.define('RandomPointsGenerator', [
|
||||||
|
'coordSystem.geo'
|
||||||
|
], function (provide, coordSystem) {
|
||||||
|
/**
|
||||||
|
* Random-генератор меток.
|
||||||
|
* @class
|
||||||
|
* @name RandomPointsGenerator
|
||||||
|
* @param {Number} count Количество меток которые надо создать.
|
||||||
|
* @example
|
||||||
|
var placemarks = RandomPointsGenerator.generate(200).atBounds(myMap.getBounds());
|
||||||
|
*/
|
||||||
|
function RandomPointsGenerator(count) {
|
||||||
|
this.count = count || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Статический метод для удобства инстанцирования.
|
||||||
|
* @static
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.generate
|
||||||
|
* @param {Number} count Количество меток которые надо создать.
|
||||||
|
* @returns {RandomPointsGenerator} Экземпляр генератора меток.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.generate = function (count) {
|
||||||
|
return new RandomPointsGenerator(count);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Устанавливает количество меток для генерации.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.generate
|
||||||
|
* @param {Number} count Количество меток которые надо создать.
|
||||||
|
* @returns {RandomPointsGenerator} Экземпляр генератора меток.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.generate = function (count) {
|
||||||
|
this.count = count;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерит случайным образом метки в области bounds.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.atBounds
|
||||||
|
* @param {Number[][]} bounds Область видимости меток.
|
||||||
|
* @returns {ymaps.Placemark[]} Массив меток.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.atBounds = function (bounds) {
|
||||||
|
// протяженность области просмотра в градусах
|
||||||
|
var span = [bounds[1][0] - bounds[0][0], bounds[1][1] - bounds[0][1]];
|
||||||
|
var points = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < this.count; i++) {
|
||||||
|
points[i] = this.createPlacemark(
|
||||||
|
[Math.random() * span[0] + bounds[0][0], Math.random() * span[1] + bounds[0][1]], i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерит случайным образом метки внутри окружности с данным центром и радиусом.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.atCenterAndRadius
|
||||||
|
* @param {Number[]} center Координаты центра окружности.
|
||||||
|
* @param {Number} radius Радиус окружности в метрах.
|
||||||
|
* @returns {ymaps.Placemark[]} Массив меток.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.atCenterAndRadius = function (center, radius) {
|
||||||
|
var points = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < this.count; i++) {
|
||||||
|
var direction = [Math.random() - Math.random(), Math.random() - Math.random()];
|
||||||
|
var distance = radius * Math.random();
|
||||||
|
var coords = coordSystem.solveDirectProblem(center, direction, distance).endPoint;
|
||||||
|
points[i] = this.createPlacemark(coords, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
* Генерит случайным образом метки внутри области с данным центром и линейными размерами.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.atCenterAndSize
|
||||||
|
* @param {Number[]} center Координаты центра области.
|
||||||
|
* @param {Number[]} size Линейные размеры области в метрах.
|
||||||
|
* @returns {ymaps.Placemark[]} Массив меток.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.atCenterAndSize = function (center, size) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создает метку по координатам.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.createPlacemark
|
||||||
|
* @param {Number[]} coordinates Массив координат.
|
||||||
|
* @param {Number} index Индекс метки.
|
||||||
|
* @returns {ymaps.Placemark} Метка.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.createPlacemark = function (coordinates, index) {
|
||||||
|
return new ymaps.GeoObject({
|
||||||
|
geometry: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: coordinates
|
||||||
|
},
|
||||||
|
properties: this.getPointData(index)
|
||||||
|
}, this.getPointOptions(index));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метод для перекрытия. Возвращает объект с данными,
|
||||||
|
* который передается как поле properties в конструктор геообъекта.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.getPointData
|
||||||
|
* @param {Number} index Индекс метки.
|
||||||
|
* @returns {Object} Данные метки.
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.getPointData = function (index) {
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метод для перекрытия. Возвращает объект с опциями,
|
||||||
|
* который передается как параметр options в конструктор геообъекта.
|
||||||
|
* @function
|
||||||
|
* @name RandomPointsGenerator.getPointOptions
|
||||||
|
* @param {Number} index Индекс метки.
|
||||||
|
* @returns {Object} Опции метки.
|
||||||
|
* @example
|
||||||
|
var generator = RandomPointsGenerator.generate(200);
|
||||||
|
// Перекрываем метод для создания меток со случайным хначением опции preset.
|
||||||
|
generator.getPointOptions = function (i) {
|
||||||
|
var presets = ['islands#blueIcon', 'islands#orangeIcon', 'islands#darkblueIcon', 'islands#pinkIcon'];
|
||||||
|
return {
|
||||||
|
preset: presets[Math.floor(Math.random() * presets.length)]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
RandomPointsGenerator.prototype.getPointOptions = function (index) {
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
provide(RandomPointsGenerator);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
e.modules.define('PieChartClusterer.component.Canvas', [
|
||||||
|
'option.Manager',
|
||||||
|
'PieChartClusterer.icon.colors'
|
||||||
|
], function (provide, OptionManager, iconColors) {
|
||||||
|
var DEFAULT_OPTIONS = {
|
||||||
|
canvasIconStrokeStyle: 'white',
|
||||||
|
canvasIconLineWidth: 2,
|
||||||
|
canvasIconCoreRadius: 23,
|
||||||
|
canvasIconCoreFillStyle: 'white'
|
||||||
|
};
|
||||||
|
|
||||||
|
var Canvas = function (size) {
|
||||||
|
this._canvas = document.createElement('canvas');
|
||||||
|
this._canvas.width = size[0];
|
||||||
|
this._canvas.height = size[1];
|
||||||
|
|
||||||
|
this._context = this._canvas.getContext('2d');
|
||||||
|
this.options = new OptionManager({});
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype.generateIconDataURL = function (styleGroups, total) {
|
||||||
|
this._drawIcon(styleGroups, total);
|
||||||
|
|
||||||
|
return this._canvas.toDataURL();
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype._drawIcon = function (styleGroups, total) {
|
||||||
|
var startAt = 0;
|
||||||
|
var endAt = 360;
|
||||||
|
var ctx = this._context;
|
||||||
|
var x = this._canvas.width / 2;
|
||||||
|
var y = this._canvas.height / 2;
|
||||||
|
var lineWidth = this.options.get('canvasIconLineWidth', DEFAULT_OPTIONS.canvasIconLineWidth);
|
||||||
|
var strokeStyle = this.options.get('canvasIconStrokeStyle', DEFAULT_OPTIONS.canvasIconStrokeStyle);
|
||||||
|
var radius = Math.floor((x + y - lineWidth) / 2);
|
||||||
|
|
||||||
|
ctx.strokeStyle = strokeStyle;
|
||||||
|
ctx.lineWidth = lineWidth;
|
||||||
|
|
||||||
|
Object.keys(styleGroups).forEach(function (style) {
|
||||||
|
var num = styleGroups[style];
|
||||||
|
|
||||||
|
endAt = startAt + (num * 360 / total);
|
||||||
|
ctx.fillStyle = this._getStyleColor(style);
|
||||||
|
|
||||||
|
if (total > num) {
|
||||||
|
startAt = this._drawSector(x, y, radius, startAt, endAt);
|
||||||
|
} else {
|
||||||
|
this._drawCircle(x, y, radius);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this._drawCore(x, y);
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype._drawCore = function (x, y) {
|
||||||
|
var ctx = this._context;
|
||||||
|
var fillStyle = this.options.get('canvasIconCoreFillStyle', DEFAULT_OPTIONS.canvasIconCoreFillStyle);
|
||||||
|
var radius = this.options.get('canvasIconCoreRadius', DEFAULT_OPTIONS.canvasIconCoreRadius);
|
||||||
|
|
||||||
|
ctx.fillStyle = fillStyle;
|
||||||
|
this._drawCircle(x, y, radius);
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype._drawCircle = function (x, y, radius) {
|
||||||
|
var ctx = this._context;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, radius, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype._drawSector = function (x, y, radius, startAt, endAt) {
|
||||||
|
var ctx = this._context;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x, y);
|
||||||
|
ctx.arc(x, y, radius, this._toRadians(startAt), this._toRadians(endAt));
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
return endAt;
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype._toRadians = function (deg) {
|
||||||
|
return deg * Math.PI / 180;
|
||||||
|
};
|
||||||
|
|
||||||
|
Canvas.prototype._getStyleColor = function (style) {
|
||||||
|
return (iconColors[style] === undefined)? style: iconColors[style];
|
||||||
|
};
|
||||||
|
|
||||||
|
provide(Canvas);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
e.modules.define('PieChartClusterer.icon.colors', [], function (provide) {
|
||||||
|
var colors = {
|
||||||
|
blue: '#1E98FF',
|
||||||
|
red: '#ED4543',
|
||||||
|
darkOrange: '#E6761B',
|
||||||
|
night: '#0E4779',
|
||||||
|
darkBlue: '#177BC9',
|
||||||
|
pink: '#F371D1',
|
||||||
|
gray: '#B3B3B3',
|
||||||
|
brown: '#793D0E',
|
||||||
|
darkGreen: '#1BAD03',
|
||||||
|
violet: '#B51EFF',
|
||||||
|
black: '#595959',
|
||||||
|
yellow: '#FFD21E',
|
||||||
|
green: '#56DB40',
|
||||||
|
orange: '#FF931E',
|
||||||
|
lightBlue: '#82CDFF',
|
||||||
|
olive: '#97A100'
|
||||||
|
};
|
||||||
|
|
||||||
|
provide(colors);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
e.modules.define('PieChartClusterer.icon.params', [
|
||||||
|
'shape.Circle',
|
||||||
|
'geometry.pixel.Circle'
|
||||||
|
], function (provide, CircleShape, PixelCircleGeometry) {
|
||||||
|
provide({
|
||||||
|
icons: {
|
||||||
|
small: {
|
||||||
|
size: [46, 46],
|
||||||
|
offset: [-23, -23],
|
||||||
|
shape: new CircleShape(new PixelCircleGeometry([0, 2], 21.5))
|
||||||
|
},
|
||||||
|
medium: {
|
||||||
|
size: [58, 58],
|
||||||
|
offset: [-29, -29],
|
||||||
|
shape: new CircleShape(new PixelCircleGeometry([0, 2], 27.5))
|
||||||
|
},
|
||||||
|
large: {
|
||||||
|
size: [71, 71],
|
||||||
|
offset: [-35.5, -35.5],
|
||||||
|
shape: new CircleShape(new PixelCircleGeometry([0, 2], 34))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numbers: [10, 100]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}(this);
|
||||||
1
public/static/js/ymaps-pie-chart-clusterer.mini2.js
Executable file
1
public/static/js/ymaps-pie-chart-clusterer.mini2.js
Executable file
@@ -0,0 +1 @@
|
|||||||
|
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('!6(t){4 e={q:t.1s.q};!6(t){1i("1V"==1I t&&"6"==1I 1J)4 t=1J("2z");t.E("Y.2A",["2w.2v"],6(t,e){t(6(t,n){4 o=n[0],r=2r.8.2q.13(n,1),a=e.2s(t.2t,{},t.2u,r);o(a)})})}(e.q);e.q.E(\'f\',[\'11\',\'Y.X\',\'Y.F\',\'f.O.1l\',\'f.1t.g\'],6(j,11,X,F,z,1H){4 1R=/#(.+?)(?=2C|2K|2L|2M|2N)/;4 f=X(6(c){f.1D.2J.13(3,c);3.k=p 1H(z.K.1j.s);3.k.c.2E(3.c)},11,{1E:6(I,T){4 1d=f.1D.1E.13(3,I,T);4 u=T.2p(6(V,12){4 d=12.c.A(\'2O\',1F);1i(d===1F){4 d=1Q(12.c.A(\'1e\',\'26#2e\'))};V[d]=++V[d]||1;9 V},{});4 S=3.k.1y(u,T.2b);4 1L={2a:[F({1h:S},z.K.1r),F({1h:S},z.K.1M),F({1h:S},z.K.1j)],2f:z.1G};1d.c.2m(1L);9 1d}});6 1Q(1e){9 1e.2j(1R)[1]}j(f)});e.q.E(\'b\',[\'1b.2h\'],6(j,1b){6 b(m){3.m=m||0}b.1P=6(m){9 p b(m)};b.8.1P=6(m){3.m=m;9 3};b.8.2o=6(w){4 1c=[w[1][0]-w[0][0],w[1][1]-w[0][1]];4 B=[];1C(4 i=0;i<3.m;i++){B[i]=3.17([l.v()*1c[0]+w[0][0],l.v()*1c[1]+w[0][1]],i)}9 B};b.8.2P=6(I,h){4 B=[];1C(4 i=0;i<3.m;i++){4 1B=[l.v()-l.v(),l.v()-l.v()];4 1p=h*l.v();4 1q=1b.2H(I,1B,1p).3p;B[i]=3.17(1q,i)}9 B};b.8.3q=6(I,s){};b.8.17=6(16,H){9 p 1s.3j({1T:{3t:\'3k\',16:16},3m:3.1n(H)},3.1m(H))};b.8.1n=6(H){9{}};b.8.1m=6(H){9{}};j(b)});e.q.E(\'f.1t.g\',[\'3w.3u\',\'f.O.U\'],6(j,1A,Z){4 L={19:\'1z\',1a:2,15:23,1f:\'1z\'};4 g=6(s){3.k=2Y.2X(\'3i\');3.k.1u=s[0];3.k.1v=s[1];3.G=3.k.30(\'2d\');3.c=p 1A({})};g.8.1y=6(u,J){3.1x(u,J);9 3.k.2W()};g.8.1x=6(u,J){4 C=0;4 D=1w;4 7=3.G;4 x=3.k.1u/2;4 y=3.k.1v/2;4 M=3.c.A(\'1a\',L.1a);4 18=3.c.A(\'19\',L.19);4 h=l.32((x+y-M)/2);7.18=18;7.M=M;3e.3f(u).3g(6(d){4 1g=u[d];D=C+(1g*1w/J);7.N=3.1W(d);1i(J>1g){C=3.1Y(x,y,h,C,D)}39{3.14(x,y,h)}},3);3.1N(x,y)};g.8.1N=6(x,y){4 7=3.G;4 N=3.c.A(\'1f\',L.1f);4 h=3.c.A(\'15\',L.15);7.N=N;3.14(x,y,h)};g.8.14=6(x,y,h){4 7=3.G;7.1X();7.1U(x,y,h,0,2*l.20);7.24();7.22()};g.8.1Y=6(x,y,h,C,D){4 7=3.G;7.1X();7.3v(x,y);7.1U(x,y,h,3.W(C),3.W(D));7.3r(x,y);7.2Z();7.24();7.22();9 D};g.8.W=6(1Z){9 1Z*l.20/2n};g.8.1W=6(d){9(Z[d]===1V)?d:Z[d]};j(g)});e.q.E(\'f.O.U\',[],6(j){4 U={2y:\'#2x\',3l:\'#2I\',2D:\'#2F\',2G:\'#25\',2l:\'#2g\',2i:\'#2k\',28:\'#3n\',3s:\'#3h\',31:\'#2V\',2R:\'#2S\',3b:\'#3a\',2c:\'#38\',36:\'#37\',3c:\'#3d\',33:\'#2U\',2T:\'#2Q\'};j(U)});e.q.E(\'f.O.1l\',[\'R.1o\',\'1T.3o.1o\'],6(j,P,Q){j({K:{1r:{s:[1S,1S],1k:[-23,-23],R:p P(p Q([0,2],21.5))},1M:{s:[1O,1O],1k:[-29,-29],R:p P(p Q([0,2],27.5))},1j:{s:[1K,1K],1k:[-35.5,-35.5],R:p P(p Q([0,2],34))}},1G:[10,2B]})})}(3);',62,219,'|||this|var||function|ctx|prototype|return||RandomPointsGenerator|options|style||PieChartClusterer|Canvas|radius||provide|_canvas|Math|count|||new|modules||size||styleGroups|random|bounds|||iconParams|get|points|startAt|endAt|define|extend|_context|index|center|total|icons|DEFAULT_OPTIONS|lineWidth|fillStyle|icon|CircleShape|PixelCircleGeometry|shape|iconUrl|geoObjects|colors|groups|_toRadians|defineClass|util|iconColors||Clusterer|geoObject|call|_drawCircle|canvasIconCoreRadius|coordinates|createPlacemark|strokeStyle|canvasIconStrokeStyle|canvasIconLineWidth|coordSystem|span|clusterPlacemark|preset|canvasIconCoreFillStyle|num|href|if|large|offset|params|getPointOptions|getPointData|Circle|distance|coords|small|ymaps|component|width|height|360|_drawIcon|generateIconDataURL|white|OptionManager|direction|for|superclass|createCluster|null|numbers|PieChartClustererCanvas|typeof|require|71|clusterOptions|medium|_drawCore|58|generate|getIconStyle|STYLE_REG_EXP|46|geometry|arc|undefined|_getStyleColor|beginPath|_drawSector|deg|PI||stroke||fill|0E4779|islands||gray||clusterIcons|length|yellow||blueIcon|clusterNumbers|177BC9|geo|pink|match|F371D1|darkBlue|set|180|atBounds|reduce|slice|Array|joinImports|name|deps|mergeImports|system|1E98FF|blue|ym|providePackage|100|Icon|darkOrange|setParent|E6761B|night|solveDirectProblem|ED4543|constructor|DotIcon|StretchyIcon|CircleIcon|CircleDotIcon|iconColor|atCenterAndRadius|97A100|violet|B51EFF|olive|82CDFF|1BAD03|toDataURL|createElement|document|closePath|getContext|darkGreen|floor|lightBlue|||green|56DB40|FFD21E|else|595959|black|orange|FF931E|Object|keys|forEach|793D0E|canvas|GeoObject|Point|red|properties|B3B3B3|pixel|endPoint|atCenterAndSize|lineTo|brown|type|Manager|moveTo|option'.split('|'),0,{}))
|
||||||
Reference in New Issue
Block a user