Improve text browser support

This commit is contained in:
Les De Ridder 2018-10-18 22:52:19 +02:00
parent 86da4c2ec3
commit f96a3ba685
5 changed files with 91 additions and 37 deletions

View File

@ -102,6 +102,18 @@ class PollController extends Controller
->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)
{
$voteCount = $poll->votes->count();
@ -122,19 +134,21 @@ class PollController extends Controller
$chartWidth = $width - 2 * $padding;
$chartHeight = $height - 2 * $padding;
$colourSquareSize = 13;
$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);
$primary = imagecolorallocate($pieChart, 0xE8, 0x3F, 0xB8);
$colours = [];
$colourSquareUris = [];
$startDegrees = 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; })->values();
debug($nonZeroOptions);
for($i = 0; $i < $poll->options->count(); $i++) {
for($i = 0; $i < $nonZeroOptions->count(); $i++) {
$option = $nonZeroOptions[$i];
//TODO: Fix gaps
@ -147,27 +161,31 @@ class PollController extends Controller
* floor($i / count($baseColours)) / (floor($nonZeroOptions->count() / count($baseColours)) + 1);
};
$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)]]);
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;
}
debug($colours);
debug($colourSquareUris);
$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);
$pieChart = $resized;
ob_start();
imagepng($pieChart);
$dataUri = "data:image/png;base64," . base64_encode(ob_get_contents());
ob_end_clean();
$dataUri = PollController::imageToDataUri($pieChart);
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)

View File

@ -10,6 +10,8 @@
<section class="grid grid--large">
<div class="textfield">
<span class="text-browser">Question:<br></span>
<input type="text" class="question" name="question" placeholder="Type your question here" required>
</div>
</section>
@ -17,6 +19,8 @@
<br>
<section>
<span class="text-browser">Options:<br></span>
@for ($i = 0; $i < 5; $i++)
<div class="grid grid--large">
<div class="textfield">
@ -30,6 +34,8 @@
</div>
</div>
@endfor
<div class="text-browser"><br></div>
</section>
<section class="grid grid--large">
@ -56,6 +62,8 @@
<input type="text" name="admin_password" class="inline-text">
<span class="post-input-label"></span>
</label>
<div class="text-browser"><br></div>
</div>
<div class="some-top-margin">
<div class="some-bottom-margin">
@ -80,9 +88,12 @@
<input type="number" min="2" max="1000" value="10" name="number_of_codes">
<span class="radio__label">codes</span>
</label>
</div>
</section>
<div class="text-browser"><br></div>
<section>
<input type="submit" class="btn" value="Create poll">
</section>

View File

@ -16,6 +16,7 @@
.some-top-margin { margin-top: 2.0rem; }
.some-more-bottom-margin { margin-bottom: 2.0rem; }
.inline-block { display: inline-block; }
.text-browser { display: none; }
.primary-box {
padding: 1rem 1rem 1rem 1rem!important;
@ -118,6 +119,8 @@
@yield('content')
</main>
<div class="text-browser"><br></div>
<footer>
<p>Dates and times are UTC.</p>
</footer>

View File

@ -11,6 +11,8 @@ $type = $poll->allow_multiple_answers ? "checkbox" : "radio";
<section class="primary-box">
<span>Your poll has been created!</span><br>
<div class="text-browser"><br></div>
<div class="some-top-margin">
@if ($poll->duplicate_vote_checking == 'codes')
<span>Voting URLs:</span>
@ -24,18 +26,22 @@ $type = $poll->allow_multiple_answers ? "checkbox" : "radio";
<section @if($new) class="some-top-margin" @endif>
@if ($hasVoted)
@if (!$new || $poll->duplicate_vote_checking != 'codes')
<div class="primary-box">
<span>You have already voted on this poll or need a code to vote.</span>
</div>
@if (!$new || $poll->duplicate_vote_checking != 'codes')
<div class="text-browser"><br></div>
@if ($poll->results_visible)
<div class="some-top-margin">
<span><a href="{{ action('PollController@viewResults', ['poll' => $poll]) }}">Results</a></span>
</div>
@endif
<div class="primary-box">
<span>You have already voted on this poll or need a code to vote.</span>
</div>
@if ($poll->results_visible)
<div class="some-top-margin">
<span><a href="{{ action('PollController@viewResults', ['poll' => $poll]) }}">Results</a></span>
</div>
@endif
@endif
@else
<div class="text-browser"><br></div>
<form action="{{ action('PollController@vote', ['poll' => $poll]) }}" method="post">
@csrf

View File

@ -7,16 +7,23 @@
<section class="primary-box">
<span>Your vote has been recorded!</span><br>
</section>
<div class="text-browser"><br></div>
@endif
@if($poll->results_visible)
@php ($sortedOptions = $poll->options->sortByDesc(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count(); }))
@php ($nonZeroOptions = $sortedOptions->filter(function($option) use($poll) { return $poll->votes->where('poll_option_id', $option->id)->count() > 0; }))
@php
$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">
<div class="some-bottom-margin">
<div class="primary-box">
@php ($total = $poll->votes->count())
@foreach ($sortedOptions as $option)
@php ($votes = $poll->votes->where('poll_option_id', $option->id)->count())
@ -24,11 +31,15 @@
<div class="some-more-bottom-margin">
<div>
<span>{{ $option->text }}</span>
<span class="text-browser">:</span>
<span style="float:right">{{ $votes }} votes</span>
</div>
<div>
<!-- TODO: title attribute -->
<div style="background-color:#e83fb8;height:2rem;width:{{ $votes / $total * 100 }}%;">
<div style="background-color:#e83fb8;height:2rem;width:{{ $total == 0 ? 0 : ($votes / $total * 100) }}%;" "{{ $total == 0 ? 0 : ($votes / $total * 100)}}% of votes">
<div class="text-browser">
<span>{{ $total == 0 ? 0 : round($votes / $total * 100, 2) }}% of votes</span>
<br><br>
</div>
</div>
</div>
</div>
@ -40,18 +51,23 @@
</div>
</div>
<div>
@php ($cache = Cache::get($poll->id))
<div class="primary-box">
<img src="{{ $cache['pie_chart']}}" style="display:block;margin: 0 auto">
<br>
@foreach ($nonZeroOptions as $option)
<!-- TODO: Generate images so this works on text browsers -->
<div style="display:inline-block;height:1rem;width:1rem;background-color:{{$cache['colours'][$option->id]}};margin-right:1rem"></div>
<span>{{ $option->text }}</span>
<br>
@endforeach
</div>
@if ($total != 0)
<div class="primary-box">
<img src="{{ $cache['pie_chart']}}" style="display:block;margin: 0 auto">
<br>
<div class="text-browser"><br></div>
@foreach ($nonZeroOptions as $option)
<img src="{{ $cache['colour_squares'][$option->id] }}" style="display:inline-block">
<span>{{ $option->text }}</span>
<br>
@endforeach
</div>
@endif
</div>
</section>
@else