Я написал некоторый код как некое доказательство концепции, которую я собираюсь затем перенести в более крупный проект, когда он заработает.
Часть, над которой я работаю, будет таблицей, содержащей различные значения, некоторые из которыхкоторые должны быть преобразованы в маленькие диаграммы в ячейке таблицы.
Например, проценты должны быть преобразованы в радиальные кольцевые диаграммы, а значения миль и минут должны быть преобразованы в маленькие столбцы со значениями на них.
Я получаю
Uncaught Error: контейнер не существует
ошибка для первой оболочки div, которую я должен поместить в ячейку таблицы, заменив номер внутри него.
Проблема в том, что, насколько я могу судить (хотя я должен быть неверным), порядок моего кода должен ссылаться на div только после его создания, и я не могу понять, почему это не так,
Вчера я полностью переработал весь свой код в совершенно новый порядок с другим способом вызова всех моих функций, и он все еще дает мне ту же ошибку.
Я использую внешнюю библиотеку progressbar.js .HTML / CSS / JS код выглядит следующим образом.Чтобы увидеть, каким должен быть конечный результат, можно найти более раннюю рабочую версию, которая использует очень небрежный обходной путь, чтобы заставить его работать: http://www.workstage.stephenirving.net.
В настоящее время я просто храню весь код в одном файле с javascript и css в заголовке html.Я попытался поместить часть JS в нижней части тела в HTML, но это тоже не сработало.
// Function initiates when DOM content is loaded and all the functions for charting is subsequently called
document.addEventListener("DOMContentLoaded", function() {
const totalRads = 9,
totalMinBars = 3,
totalMileBars = 3;
totalBars = totalMinBars + totalMileBars;
let colValPairs = getColVals(totalRads, totalBars);
setColChartWrappers(totalRads, totalBars);
generateCharts(colValPairs, totalRads, totalMinBars, totalMileBars);
});
// Table value getter function
function getColVals(totalRads, totalBars) {
'use strict';
const totalCharts = totalRads + totalBars; // The combined total number of bars and radials
let colVals = new Array(), // An array of all the numbers that will be converted into radials/bars
cellIds = new Array(), // An array containing all the table cell IDS for cells containing numbers
idValPairs = new Object();
for (let i = 0; i < totalCharts; i++) {
cellIds[i] = "col0num" + i;
// Get the contents of table cells, this is the progress number
colVals[i] = document.getElementById(cellIds[i]).innerHTML;
idValPairs[cellIds[i]] = colVals[i];
}
return idValPairs;
}
// Setter function that replaces the numbers in the cells with the div containers for the graphs
function setColChartWrappers(totalRads, totalBars) {
const chartColor = '#58b86b', // Move this line when done
animTime = 1400, // The time it will take the radial to reach 100% completion, in milliseconds
minsMax = 200; // The max value for minute bar charts
let wrapperNames = new Array(), // Array for the names of all the wrapper cells for the radials
cellIds = new Array(); // An array containing all the table cell IDS for cells containing numbers
i = 0;
for (let i = 0; i < (totalRads + totalBars); i++) {
wrapperNames[i] = "chart_wrapper" + i;
cellIds[i] = "col0num" + i;
if (i < totalRads) {
document.getElementById(cellIds[i]).innerHTML = '<div class="container"><div id="' + wrapperNames[i] +
'" class="rad-wrapper"></div></div>';
} else {
document.getElementById(cellIds[i]).innerHTML = '<div class="container"><div id="' + wrapperNames[i] +
'" class="bar-wrapper"></div></div>';
}
}
}
/*********************************************************************************
* FUNC : createRadial
* PURP : This function will create and return a small radial graph object.
* INPUT : * wrapperName - Name associated with the div wrapper where the radial will go. (chart_wrapperX)
* * radColor - The color the created radial will be
* * animTime - The amount of time it will take to reach 100% completion in ms
* OUTPUT: * rad - The returned radial graph object
**********************************************************************************/
function createRadial(wrapperName, radColor, animTime) {
const startColor = '#a0d6aa'; // Create the starting color for the radial (20% lighter than radColor)
// Create a radial
let rad = new ProgressBar.Circle(wrapperName, {
color: radColor, // Set the font color of the number and % sign in the center of the radial
strokeWidth: 9, // To prevent clipping, make the same as the max width it will animate to
trailWidth: 9, // The width of the trail the radial will animate along
trailColor: '#e2e2e2', // The color of the trail
easing: 'easeInOut', // Animation easing function
duration: animTime, // Sets the total time in milliseconds for the animation to reach 100%
text: {
autoStyleContainer: false
},
// Changes loading bar color & width as it progresses.
// Keep in mind: The bar radial bar only reach the stated 'to' color and width when it reaches 100%
from: { // Starting color and width
color: startColor,
width: 9
},
to: { // Ending color and width
color: radColor,
width: 9 // To prevent clipping, make width here the same as strokeWidth
},
// Animate the path of the radial and the text inside it
step: function step(state, circle) {
circle.path.setAttribute('stroke', state.color);
circle.path.setAttribute('stroke-width', state.width);
let value = Math.round(circle.value() * 100);
circle.setText(value + '%');
}
});
// Set the text style of above radial
rad.text.style.fontFamily = '"Roboto", Arial, Helvetica, sans-serif;';
rad.text.style.fontSize = '20px';
rad.text.style.fontWeight = '700'; // Make the font weight bold
return rad;
}
/*********************************************************************************
* FUNC : createBar
* PURP : This function will create and return a small bar graph object.
* INPUT : * wrapperName - Name associated with the div wrapper where the bar will go. (chart_wrapperX)
* * progressNum - The number that is in the cell being replaced with the bar
* * barColor - The color the created bar will be
* * animTime - The amount of time it will take to reach 100% completion in ms
* * maxVal - The maximum value or range that the graph will rise to
* OUTPUT: * bar - The returned bar graph object
**********************************************************************************/
function createBar(wrapperName, progressNum, barColor, animTime, maxVal) {
'use strict';
const startColor = '#a0d6aa'; // Create the starting color for the bar (20% lighter than barColor)
let progress, // Initialize variable for the progress the bar will animate to
endText, // If maxVal = 50 endText is 'miles', otherwise it is 'mins'
endColor = barColor; // Initialize variable for the color the bar will end up
if (maxVal == 50) {
endText = 'miles';
} else {
endText = 'mins';
}
if (progressNum > maxVal) {
endColor = '#2b6537';
} // Darken the ending color if the it goes higher than the maximum
let bar = new ProgressBar.Line(wrapperName, {
color: barColor, // Sets the color that the bar will be
trailColor: '#e2e2e2', // The color of the trail
easing: 'easeInOut', // Animation easing function
duration: animTime, // Sets the total time in milliseconds for the animation to reach 100%
svgStyle: {
width: '98%',
height: '98%'
},
text: {
style: {
left: '-38%', // Due to rotation, 'left' attribute is really 'bottom' attribute
top: '40%' // Due to rotation, 'top' attribute is really 'left' attribute
},
autoStyleContainer: false
},
from: {
color: startColor
}, // Sets the starting color of the bar
to: {
color: endColor
}, // Sets the final color of the bar if and when it reaches 100%
// Animate the path of the bar and the text inside it
step: function step(state, bar) {
bar.path.setAttribute('stroke', state.color);
let value = Math.round((bar.value() * maxVal) * 10) / 10;
bar.setText(value + ' ' + endText);
}
});
bar.text.style.color = '#fff'; // Set text color
bar.text.style.whiteSpace = 'nowrap'; // Keep text from wrapping
bar.text.style.position = 'absolute';
bar.text.style.width = '100%';
bar.text.style.fontfamily = '"Roboto", Arial, Helvetica, sans-serif'; // Text font
bar.text.style.fontSize = '1em'; // Text font size
bar.text.style.fontWeight = '700'; // Make the font weight bold
bar.text.style.transform = 'rotate(90deg)'; // Rotate the text back so that it is not sideways.
// Add shadow to text to make it easier to see on light bg
bar.text.style.textShadow = '1px 1px 0px rgba(150, 150, 150, 0.6)';
return bar;
}
// Function generate the chart elements in the table
function generateCharts(idValPairs, totalRads, totalMinBars, totalMileBars) {
'use strict';
const chartColor = '#58b86b', // Set the color the radial will be
animTime = 1400, // The time it will take the radial to reach 100% completion, in milliseconds
totalBars = totalMinBars + totalMileBars,
totalCharts = totalRads + totalBars;
let i = 0,
wrapperNames = new Array(), // Array for the names of all the wrapper cells for the radials
radObjects = new Array(),
barOjects = new Array();
for (const key of Object.keys(idValPairs)) {
wrapperNames[i] = "chart_wrapper" + i;
radObjects[i] = createRadial(wrapperNames[i], chartColor, animTime);
if (i < totalMileBars) {
barObjects[i] = createBar(wrapperNames[i], idValPairs[key], chartColor, animTime, 50);
} else {
barObjects[i] = createBar(wrapperNames[i], idValPairs[key], chartColor, animTime, minuteMax);
}
i++;
}
i = 0;
for (const key of Object.keys(idValPairs)) {
if (i < totalRads) {
radObjects[i].animate((idValPairs[key] / 100));
} else if (i < (totalRads + totalMileBars)) {
barObjects[i].animate((idValPairs[key] / 50));
} else {
barObjects[i].animate((idValPairs[key] / 200));
}
i++;
}
}
body {
font-family: 'Roboto', Helvetica, sans-serif;
}
table {
border: 2px solid black;
float: left;
display: inline;
}
th {
border-bottom: 2px solid black;
}
td {
border: 1px solid black;
text-align: center;
height: 100px;
width: 120px;
color: white;
}
.container {
height: 100%;
width: 100%;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.rad-wrapper {
margin: 0 auto;
padding: 0;
width: 5.8em;
/* This is the size of the radial, make it equal to height */
height: 5.8em;
/* This is the size of the radial, make it equal to width */
position: relative;
}
.bar-wrapper {
width: 5.8em;
/* This is the height of the bar (due to rotation transform) */
height: 7em;
/* This is the width of the bar */
position: relative;
margin: 0 auto;
padding: 0;
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RADIAL AND BAR TEST</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<link href="https://fonts.googleapis.com/css?family=Roboto:700" rel="stylesheet">
<script src="https://raw.githubusercontent.com/kimmobrunfeldt/progressbar.js/master/dist/progressbar.min.js"></script>
</head>
<body>
<table>
<tr>
<th colspan="3">EXAMPLE NUMBERS</th>
</tr>
<tr>
<td id="col0num0">38</td>
<td id="col0num1">52</td>
<td id="col0num2">49</td>
</tr>
<tr>
<td id="col0num3">56</td>
<td id="col0num4">61</td>
<td id="col0num5">30</td>
</tr>
<tr>
<td id="col0num6">33</td>
<td id="col0num7">29</td>
<td id="col0num8">32</td>
</tr>
<tr>
<!-- Bars begin -->
<td id="col0num9">9.9</td>
<td id="col0num10">8.5</td>
<td id="col0num11">11.2</td>
</tr>
<tr>
<!-- minute bar (Max 200) -->
<td id="col0num12">106.9</td>
<td id="col0num13">104.8</td>
<td id="col0num14">83.5</td>
</tr>
</table>
</body>
</html>