Improve text browser support
This commit is contained in:
parent
86da4c2ec3
commit
f96a3ba685
|
@ -102,6 +102,18 @@ class PollController extends Controller
|
||||||
->with('voted', $voted);
|
->with('voted', $voted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function imageToDataUri($image)
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
imagepng($image);
|
||||||
|
$dataUri = "data:image/png;base64," . base64_encode(ob_get_contents());
|
||||||
|
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
return $dataUri;
|
||||||
|
}
|
||||||
|
|
||||||
private function createPieChart(Poll $poll)
|
private function createPieChart(Poll $poll)
|
||||||
{
|
{
|
||||||
$voteCount = $poll->votes->count();
|
$voteCount = $poll->votes->count();
|
||||||
|
@ -122,19 +134,21 @@ class PollController extends Controller
|
||||||
$chartWidth = $width - 2 * $padding;
|
$chartWidth = $width - 2 * $padding;
|
||||||
$chartHeight = $height - 2 * $padding;
|
$chartHeight = $height - 2 * $padding;
|
||||||
|
|
||||||
|
$colourSquareSize = 13;
|
||||||
|
|
||||||
$pieChart = imagecreatetruecolor($width, $height);
|
$pieChart = imagecreatetruecolor($width, $height);
|
||||||
imagefill($pieChart, 0, 0, imagecolorallocate($pieChart, 0xFF, 0xFF, 0xFF));
|
$transparent = imagecolorallocatealpha($pieChart, 0xFF, 0xFF, 0xFF, 0x7F);
|
||||||
|
imagefill($pieChart, 0, 0, $transparent);
|
||||||
|
imagesavealpha($pieChart, true);
|
||||||
imageantialias($pieChart, true);
|
imageantialias($pieChart, true);
|
||||||
|
|
||||||
$primary = imagecolorallocate($pieChart, 0xE8, 0x3F, 0xB8);
|
$colourSquareUris = [];
|
||||||
|
|
||||||
$colours = [];
|
|
||||||
|
|
||||||
$startDegrees = 0;
|
$startDegrees = 0;
|
||||||
$sortedOptions = $poll->options->sortByDesc(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count(); });
|
$sortedOptions = $poll->options->sortByDesc(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count(); });
|
||||||
$nonZeroOptions = $sortedOptions->filter(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count() > 0; })->values();
|
$nonZeroOptions = $sortedOptions->filter(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count() > 0; })->values();
|
||||||
debug($nonZeroOptions);
|
debug($nonZeroOptions);
|
||||||
for($i = 0; $i < $poll->options->count(); $i++) {
|
for($i = 0; $i < $nonZeroOptions->count(); $i++) {
|
||||||
$option = $nonZeroOptions[$i];
|
$option = $nonZeroOptions[$i];
|
||||||
|
|
||||||
//TODO: Fix gaps
|
//TODO: Fix gaps
|
||||||
|
@ -147,27 +161,31 @@ class PollController extends Controller
|
||||||
* floor($i / count($baseColours)) / (floor($nonZeroOptions->count() / count($baseColours)) + 1);
|
* floor($i / count($baseColours)) / (floor($nonZeroOptions->count() / count($baseColours)) + 1);
|
||||||
};
|
};
|
||||||
$colour = imagecolorallocate($pieChart, $c(0), $c(1), $c(2));
|
$colour = imagecolorallocate($pieChart, $c(0), $c(1), $c(2));
|
||||||
$colours[$option->id] = '#' . dechex($c(0) << 16 | $c(1) << 8 | $c(2) << 0);
|
|
||||||
|
|
||||||
debug([$option->text, [$startDegrees, $endDegrees], [$c(0), $c(1), $c(2)]]);
|
debug([$option->text, [$startDegrees, $endDegrees], [$c(0), $c(1), $c(2)]]);
|
||||||
|
|
||||||
imagefilledarc($pieChart, $width / 2, $height / 2, $chartWidth, $chartHeight, $startDegrees, $endDegrees, $colour, IMG_ARC_PIE);
|
imagefilledarc($pieChart, $width / 2, $height / 2, $chartWidth, $chartHeight, $startDegrees, $endDegrees, $colour, IMG_ARC_PIE);
|
||||||
|
|
||||||
|
$colourSquare = imagecreatetruecolor($colourSquareSize, $colourSquareSize);
|
||||||
|
$colourSquareColour = imagecolorallocate($colourSquare, $c(0), $c(1), $c(2));
|
||||||
|
imagefill($colourSquare, 0, 0, $colourSquareColour);
|
||||||
|
$colourSquareUris[$option->id] = PollController::imageToDataUri($colourSquare);
|
||||||
|
|
||||||
$startDegrees = $endDegrees;
|
$startDegrees = $endDegrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug($colours);
|
debug($colourSquareUris);
|
||||||
|
|
||||||
$resized = imagecreatetruecolor($width / $supersamplingFactor, $height / $supersamplingFactor);
|
$resized = imagecreatetruecolor($width / $supersamplingFactor, $height / $supersamplingFactor);
|
||||||
|
imagecolortransparent($resized, imagecolorallocatealpha($resized, 0, 0, 0, 0x7F));
|
||||||
|
imagealphablending($resized, false);
|
||||||
|
imagesavealpha($resized, true);
|
||||||
imagecopyresampled($resized, $pieChart, 0, 0, 0, 0, $width / $supersamplingFactor, $height / $supersamplingFactor, $width, $height);
|
imagecopyresampled($resized, $pieChart, 0, 0, 0, 0, $width / $supersamplingFactor, $height / $supersamplingFactor, $width, $height);
|
||||||
$pieChart = $resized;
|
$pieChart = $resized;
|
||||||
|
|
||||||
ob_start();
|
$dataUri = PollController::imageToDataUri($pieChart);
|
||||||
imagepng($pieChart);
|
|
||||||
$dataUri = "data:image/png;base64," . base64_encode(ob_get_contents());
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
Cache::put($poll->id, ['vote_count' => $voteCount, 'pie_chart' => $dataUri, 'colours' => $colours], now()->addDays(1));
|
Cache::put($poll->id, ['vote_count' => $voteCount, 'pie_chart' => $dataUri, 'colour_squares' => $colourSquareUris], now()->addDays(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasVoted(Request $request, Poll $poll)
|
public function hasVoted(Request $request, Poll $poll)
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
<section class="grid grid--large">
|
<section class="grid grid--large">
|
||||||
<div class="textfield">
|
<div class="textfield">
|
||||||
|
<span class="text-browser">Question:<br></span>
|
||||||
|
|
||||||
<input type="text" class="question" name="question" placeholder="Type your question here" required>
|
<input type="text" class="question" name="question" placeholder="Type your question here" required>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -17,6 +19,8 @@
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
<span class="text-browser">Options:<br></span>
|
||||||
|
|
||||||
@for ($i = 0; $i < 5; $i++)
|
@for ($i = 0; $i < 5; $i++)
|
||||||
<div class="grid grid--large">
|
<div class="grid grid--large">
|
||||||
<div class="textfield">
|
<div class="textfield">
|
||||||
|
@ -30,6 +34,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endfor
|
@endfor
|
||||||
|
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="grid grid--large">
|
<section class="grid grid--large">
|
||||||
|
@ -56,6 +62,8 @@
|
||||||
<input type="text" name="admin_password" class="inline-text">
|
<input type="text" name="admin_password" class="inline-text">
|
||||||
<span class="post-input-label"></span>
|
<span class="post-input-label"></span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="some-top-margin">
|
<div class="some-top-margin">
|
||||||
<div class="some-bottom-margin">
|
<div class="some-bottom-margin">
|
||||||
|
@ -80,9 +88,12 @@
|
||||||
<input type="number" min="2" max="1000" value="10" name="number_of_codes">
|
<input type="number" min="2" max="1000" value="10" name="number_of_codes">
|
||||||
<span class="radio__label">codes</span>
|
<span class="radio__label">codes</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<input type="submit" class="btn" value="Create poll">
|
<input type="submit" class="btn" value="Create poll">
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
.some-top-margin { margin-top: 2.0rem; }
|
.some-top-margin { margin-top: 2.0rem; }
|
||||||
.some-more-bottom-margin { margin-bottom: 2.0rem; }
|
.some-more-bottom-margin { margin-bottom: 2.0rem; }
|
||||||
.inline-block { display: inline-block; }
|
.inline-block { display: inline-block; }
|
||||||
|
.text-browser { display: none; }
|
||||||
|
|
||||||
.primary-box {
|
.primary-box {
|
||||||
padding: 1rem 1rem 1rem 1rem!important;
|
padding: 1rem 1rem 1rem 1rem!important;
|
||||||
|
@ -118,6 +119,8 @@
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<p>Dates and times are UTC.</p>
|
<p>Dates and times are UTC.</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -11,6 +11,8 @@ $type = $poll->allow_multiple_answers ? "checkbox" : "radio";
|
||||||
<section class="primary-box">
|
<section class="primary-box">
|
||||||
<span>Your poll has been created!</span><br>
|
<span>Your poll has been created!</span><br>
|
||||||
|
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
|
|
||||||
<div class="some-top-margin">
|
<div class="some-top-margin">
|
||||||
@if ($poll->duplicate_vote_checking == 'codes')
|
@if ($poll->duplicate_vote_checking == 'codes')
|
||||||
<span>Voting URLs:</span>
|
<span>Voting URLs:</span>
|
||||||
|
@ -24,18 +26,22 @@ $type = $poll->allow_multiple_answers ? "checkbox" : "radio";
|
||||||
|
|
||||||
<section @if($new) class="some-top-margin" @endif>
|
<section @if($new) class="some-top-margin" @endif>
|
||||||
@if ($hasVoted)
|
@if ($hasVoted)
|
||||||
@if (!$new || $poll->duplicate_vote_checking != 'codes')
|
@if (!$new || $poll->duplicate_vote_checking != 'codes')
|
||||||
<div class="primary-box">
|
<div class="text-browser"><br></div>
|
||||||
<span>You have already voted on this poll or need a code to vote.</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($poll->results_visible)
|
<div class="primary-box">
|
||||||
<div class="some-top-margin">
|
<span>You have already voted on this poll or need a code to vote.</span>
|
||||||
<span><a href="{{ action('PollController@viewResults', ['poll' => $poll]) }}">Results</a></span>
|
</div>
|
||||||
</div>
|
|
||||||
@endif
|
@if ($poll->results_visible)
|
||||||
|
<div class="some-top-margin">
|
||||||
|
<span><a href="{{ action('PollController@viewResults', ['poll' => $poll]) }}">Results</a></span>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
@endif
|
||||||
@else
|
@else
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
|
|
||||||
<form action="{{ action('PollController@vote', ['poll' => $poll]) }}" method="post">
|
<form action="{{ action('PollController@vote', ['poll' => $poll]) }}" method="post">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,23 @@
|
||||||
<section class="primary-box">
|
<section class="primary-box">
|
||||||
<span>Your vote has been recorded!</span><br>
|
<span>Your vote has been recorded!</span><br>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<div class="text-browser"><br></div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($poll->results_visible)
|
@if($poll->results_visible)
|
||||||
@php ($sortedOptions = $poll->options->sortByDesc(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count(); }))
|
@php
|
||||||
@php ($nonZeroOptions = $sortedOptions->filter(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count() > 0; }))
|
$sortedOptions = $poll->options->sortByDesc(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count(); });
|
||||||
|
$nonZeroOptions = $sortedOptions->filter(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count() > 0; });
|
||||||
|
|
||||||
|
$cache = Cache::get($poll->id);
|
||||||
|
|
||||||
|
$total = $cache['vote_count'];
|
||||||
|
@endphp
|
||||||
|
|
||||||
<section class="grid grid--large some-top-margin">
|
<section class="grid grid--large some-top-margin">
|
||||||
<div class="some-bottom-margin">
|
<div class="some-bottom-margin">
|
||||||
<div class="primary-box">
|
<div class="primary-box">
|
||||||
@php ($total = $poll->votes->count())
|
|
||||||
|
|
||||||
@foreach ($sortedOptions as $option)
|
@foreach ($sortedOptions as $option)
|
||||||
@php ($votes = $poll->votes->where('poll_option_id', $option->id)->count())
|
@php ($votes = $poll->votes->where('poll_option_id', $option->id)->count())
|
||||||
|
@ -24,11 +31,15 @@
|
||||||
<div class="some-more-bottom-margin">
|
<div class="some-more-bottom-margin">
|
||||||
<div>
|
<div>
|
||||||
<span>{{ $option->text }}</span>
|
<span>{{ $option->text }}</span>
|
||||||
|
<span class="text-browser">:</span>
|
||||||
<span style="float:right">{{ $votes }} votes</span>
|
<span style="float:right">{{ $votes }} votes</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<!-- TODO: title attribute -->
|
<div style="background-color:#e83fb8;height:2rem;width:{{ $total == 0 ? 0 : ($votes / $total * 100) }}%;" "{{ $total == 0 ? 0 : ($votes / $total * 100)}}% of votes">
|
||||||
<div style="background-color:#e83fb8;height:2rem;width:{{ $votes / $total * 100 }}%;">
|
<div class="text-browser">
|
||||||
|
<span>{{ $total == 0 ? 0 : round($votes / $total * 100, 2) }}% of votes</span>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,18 +51,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@php ($cache = Cache::get($poll->id))
|
|
||||||
|
|
||||||
<div class="primary-box">
|
@if ($total != 0)
|
||||||
<img src="{{ $cache['pie_chart']}}" style="display:block;margin: 0 auto">
|
<div class="primary-box">
|
||||||
<br>
|
<img src="{{ $cache['pie_chart']}}" style="display:block;margin: 0 auto">
|
||||||
@foreach ($nonZeroOptions as $option)
|
|
||||||
<!-- TODO: Generate images so this works on text browsers -->
|
<br>
|
||||||
<div style="display:inline-block;height:1rem;width:1rem;background-color:{{$cache['colours'][$option->id]}};margin-right:1rem"></div>
|
|
||||||
<span>{{ $option->text }}</span>
|
<div class="text-browser"><br></div>
|
||||||
<br>
|
|
||||||
@endforeach
|
@foreach ($nonZeroOptions as $option)
|
||||||
</div>
|
<img src="{{ $cache['colour_squares'][$option->id] }}" style="display:inline-block">
|
||||||
|
<span>{{ $option->text }}</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@else
|
@else
|
||||||
|
|
Loading…
Reference in New Issue